JVM调优(by quqi99)

2024-03-12 00:48
文章标签 java jvm 调优 quqi99

本文主要是介绍JVM调优(by quqi99),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

JVM调优(by quqi99)

作者:张华 发表于:2010-01-27

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明

理论参考:

JAVA性能优化—Sun Hotspot JDK JVM参数设置

http://www.hashei.me/2009/05/tuning-the-sun-hotspot-jdk.html

我的做法:

去掉

-Xmx512 -client -Dsun.rmi.dgc.server.gcInterval=3600000

-Dsun.rmi.dgc.client.gcInterval=3600000

添加

-Dcom.sun.enterprise.server.ss.ASQuickStartup=false

-server -XX:+AggressiveHeap –Xmx1024m –Xms1024m -Xss128k

-XX:+DisableExplicitGC

-XX:ParallelGCThreads=N -XX:+UseParallelOldGC

-XX:LargePageSizeInBytes=256m

最近对JVM的参数重新看了下, 把应用的JVM参数调整了下。 几个重要的参数

-server -Xmx3g -Xms3g -XX:MaxPermSize=128m
-XX:NewRatio=1 eden/old 的比例
-XX:SurvivorRatio=8 s/e的比例
-XX:+UseParallelGC
-XX:ParallelGCThreads=8
-XX:+UseParallelOldGC 这个是JAVA 6出现的参数选项
-XX:LargePageSizeInBytes =128m 内存页的大小, 不可设置过大, 会影响Perm的大小。
-XX:+UseFastAccessorMethods 原始类型的快速优化
-XX:+DisableExplicitGC 关闭System.gc()



另外 -Xss 是线程栈的大小, 这个参数需要严格的测试, 一般小的应用, 如果栈不是很深, 应该是128k够用的, 不过,我们的应用调用深度比较大, 还需要做详细的测试。 这个选项对性能的影响比较大。 建议使用256K的大小.

例子:

-server -Xmx3g -Xms3g -Xmn=1g -XX:MaxPermSize=128m -Xss256k -XX:MaxTenuringThreshold=10 -XX:+DisableExplicitGC -XX:+UseParallelGC -XX:+UseParallelOld GC -XX:LargePageSizeInBytes =128m -XX:+UseFastAccessorMethods -XX:+AggressiveOpts -XX:+UseBiasedLocking 

-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintGCDetails 打印参数

=================================================================

另外对于大内存设置的要求:

Linux :
Large page support is included in 2.6 kernel. Some vendors have backported the code to their 2.4 based releases. To check if your system can support large page memory, try the following:

# cat /proc/meminfo | grep Huge
HugePages_Total: 0
HugePages_Free: 0
Hugepagesize: 2048 kB
#

If the output shows the three "Huge" variables then your system can support large page memory, but it needs to be configured. If the command doesn't print out anything, then large page support is not available. To configure the system to use large page memory, one must log in as root, then:

  1. Increase SHMMAX value. It must be larger than the Java heap size. On a system with 4 GB of physical RAM (or less) the following will make all the memory sharable:

    # echo 4294967295 > /proc/sys/kernel/shmmax

  2. Specify the number of large pages. In the following example 3 GB of a 4 GB system are reserved for large pages (assuming a large page size of 2048k, then 3g = 3 x 1024m = 3072m = 3072 * 1024k = 3145728k, and 3145728k / 2048k = 1536):

    # echo 1536 > /proc/sys/vm/nr_hugepages

Note the /proc values will reset after reboot so you may want to set them in an init script (e.g. rc.local or sysctl.conf).

=============================================
这个设置, 目前观察下来的结果是EDEN区域收集明显速度比较快, 最多几个ms, 但是,对于FGC, 大约需要0。9, 但是发生时间非常的长, 应该是影响不大。 但是对于非web应用的中间件服务, 这个设置很要不得, 可能导致很严重延迟效果. 因此, CMS必然需要被使用, 下面是CMS的重要参数介绍

关于CMS的设置:

使用CMS的前提条件是你有比较的长生命对象, 比如有200M以上的OLD堆占用。 那么这个威力非常猛, 可以极大的提高的FGC的收集能力。 如果你的OLD占用非常的少, 别用了, 绝对降低你性能, 因为CMS收集有2个STOP WORLD的行为。 OLD少的清情况, 根据我的测试, 使用并行收集参数会比较好。


-XX:+UseConcMarkSweepGC 使用CMS内存收集
-XX:+AggressiveHeap 特别说明下:(我感觉对于做java cache应用有帮助)

  • 试图是使用大量的物理内存
  • 长时间大内存使用的优化,能检查计算资源(内存, 处理器数量)
  • 至少需要256MB内存
  • 大量的CPU/内存, (在1.4.1在4CPU的机器上已经显示有提升)

-XX:+UseParNewGC 允许多线程收集新生代
-XX:+CMSParallelRemarkEnabled 降低标记停顿

-XX+UseCMSCompactAtFullCollection 在FULL GC的时候, 压缩内存, CMS是不会移动内存的, 因此, 这个非常容易产生碎片, 导致内存不够用, 因此, 内存的压缩这个时候就会被启用。 增加这个参数是个好习惯。


压力测试下合适结果:

-server -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:MaxTenuringThreshold=31 -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes =128m -XX:+UseFastAccessorMethods

由于Jdk1.5.09及之前的bug, 因此, CMS下的GC, 在这些版本的表现是十分糟糕的。 需要另外2个参数来控制cms的启动时间:

-XX:+UseCMSInitiatingOccupancyOnly 仅仅使用手动定义初始化定义开始CMS收集

-XX:CMSInitiatingOccupancyFraction=70 CMS堆上, 使用70%后开始CMS收集。

使用CMS的好处是用尽量少的新生代、,我的经验值是128M-256M, 然后老生代利用CMS并行收集, 这样能保证系统低延迟的吞吐效率。 实际上cms的收集停顿时间非常的短,2G的内存, 大约20-80ms的应用程序停顿时间。

=========系统情况介绍========================

这个例子是测试系统12小时运行后的情况:

$uname -a

2.4.21-51.EL3.customsmp #1 SMP Fri Jun 27 10:44:12 CST 2008 i686 i686 i386 GNU/Linux

$ free -m
total used free shared buffers cached
Mem: 3995 3910 85 0 162 1267
-/+ buffers/cache: 2479 1515
Swap: 2047 0 2047

$ jstat -gcutil 23959 1000

S0 S1 E O P YGC YGCT FGC FGCT GCT
59.06 0.00 45.77 44.45 56.88 15204 324.023 66 1.668 325.691
0.00 39.66 27.53 44.73 56.88 15205 324.046 66 1.668 325.715
53.42 0.00 22.80 44.73 56.88 15206 324.073 66 1.668 325.741
0.00 44.90 13.73 44.76 56.88 15207 324.094 66 1.668 325.762
51.70 0.00 19.03 44.76 56.88 15208 324.118 66 1.668 325.786
0.00 61.62 19.44 44.98 56.88 15209 324.148 66 1.668 325.816
53.03 0.00 14.00 45.09 56.88 15210 324.172 66 1.668 325.840
53.03 0.00 87.87 45.09 56.88 15210 324.172 66 1.668 325.840
0.00 50.49 72.00 45.22 56.88 15211 324.198 66 1.668 325.866

GC参数配置:

JAVA_OPTS=" -server -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:MaxTenuringThreshold=31 -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes =128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "

实际上我们可以看到并行young gc执行时间是: 324.198s/15211=20ms, cms的执行时间是 1.668/66=25ms. 当然严格来说, 这么算是不对的, 世界停顿的时间要比这是数据稍微大5-10ms. 对我们来说如果不输出日志, 对我们是有参考意义的。

32位系统下, 设置成2G, 非常危险, 除非你确定你的应用占用的native内存很少, 不然可能导致jvm直接crash。

-XX:+AggressiveOpts 加快编译

-XX:+UseBiasedLocking 锁机制的性能改善。

这篇关于JVM调优(by quqi99)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/799630

相关文章

springboot rocketmq配置生产者和消息者的步骤

《springbootrocketmq配置生产者和消息者的步骤》本文介绍了如何在SpringBoot中集成RocketMQ,包括添加依赖、配置application.yml、创建生产者和消费者,并展... 目录1. 添加依赖2. 配置application.yml3. 创建生产者4. 创建消费者5. 使用在

Spring Retry 实现乐观锁重试实践记录

《SpringRetry实现乐观锁重试实践记录》本文介绍了在秒杀商品SKU表中使用乐观锁和MybatisPlus配置乐观锁的方法,并分析了测试环境和生产环境的隔离级别对乐观锁的影响,通过简单验证,... 目录一、场景分析 二、简单验证 2.1、可重复读 2.2、读已提交 三、最佳实践 3.1、配置重试模板

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

Java中有什么工具可以进行代码反编译详解

《Java中有什么工具可以进行代码反编译详解》:本文主要介绍Java中有什么工具可以进行代码反编译的相关资,料,包括JD-GUI、CFR、Procyon、Fernflower、Javap、Byte... 目录1.JD-GUI2.CFR3.Procyon Decompiler4.Fernflower5.Jav

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

Java对象和JSON字符串之间的转换方法(全网最清晰)

《Java对象和JSON字符串之间的转换方法(全网最清晰)》:本文主要介绍如何在Java中使用Jackson库将对象转换为JSON字符串,并提供了一个简单的工具类示例,该工具类支持基本的转换功能,... 目录前言1. 引入 Jackson 依赖2. 创建 jsON 工具类3. 使用示例转换 Java 对象为

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

Java中的Cursor使用详解

《Java中的Cursor使用详解》本文介绍了Java中的Cursor接口及其在大数据集处理中的优势,包括逐行读取、分页处理、流控制、动态改变查询、并发控制和减少网络流量等,感兴趣的朋友一起看看吧... 最近看代码,有一段代码涉及到Cursor,感觉写法挺有意思的。注意是Cursor,而不是Consumer