JVM常用性能调优参数总结

不是本人写的。看到不错的资料学习下。。。

栈设置

-Xoss 设置本地方法栈大小;
-Xss 设置栈的大小,默认值1024k;
-XX:+DoEscapeAnalysis 开启逃逸分析(大型应用可能出现开启逃逸分析性能有所下降,1.6.23默认开启)
-XX:+EliminateAllocations 开启标量替换
-XX:+PrintEscapeAnalysis 开启逃逸分析性能的输出
-XX:+PrintEliminateAllocations 输出标量替换的情况
逃逸分析带来的好处:定义:动态分析对象的作用域,当对象在一个方法中被定义,可能会被外部方法引用,甚至可能被外部线程引用(赋值变量或者可以在其他的线程运用变量等)。1.栈上分配;2.锁消除;3.标量替换

堆设置

基础相关设置:
-Xms:初始堆大小
-Xmx:最大堆大小
-XX:NewSize=n 设置年轻代大小
-XX:NewRatio=n 设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n 年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
-XX:MaxPermSize=n:设置持久代大小
(注:在1.8这个内存空间被完全的移除 JVM参数PermSize 和 MaxPermSize会被忽略,当前在启动时会有警告信息,取而代之的是MetaSpace)
-XX:PretenureSizeThreshold=N当创建的对象超过指定大小时,直接把对象分配在老年代。
-XX:MaxTenuringThreshold=N 参数用于设定对象最大年龄阈值。对象在两个survivor区每复制(Minor gc)一次,年龄就增长一岁,当超过指定最大随时时转移到老年代中。
-XX:MaxDirectMemorySize 此参数的含义是当Direct ByteBuffer分配的堆外内存到达指定大小后,即触发Full GC。注意该值是有上限的,默认是java堆的最大值。
-XX:-HandlePromotionFailure 在发送minor gc之前,虚拟机会首先检查老年代最大可连续空间是否大于新生代所有对象总和,如果这个条件成立,可以确保这次minor gc是安全的,如果不成立,虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试一次minor gc,尽管这次minor gc是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那么这时也要改为一次Full gc。在jdk1.6 update24之后,HandlePromotionFailure参数不会影响虚拟机空间分配担保策略,虚拟机改为,只要老年代最大连续空间大于新生代对象总和或者大于历次晋升平均大小,都将进行minor gc,否则将进行Full gc。

TLAB相关设置:
-XX:+UseTLAB 使用ThreadLocalAllocationBuffer,注意,CPU密集型业务推荐使用,减少因多线程共用堆区发生抢占申请空间上锁而等待;但会有内存碎片产生,youngc的频率可能上升;
-XX:+TLABSize 设置TLAB大小,默认为eden的1%,需要根据业务场景调整;
-XX:TLABRefillWasteFraction 设置进入TLAB空间的比例阈值,大于此值在共用堆区创建,小于此值放在TLAB创建,运行java -XX:+PrintFlagsFinal -version | grep "TLABRefillWasteFraction" --col 可知默认值为64;
-XX:+PrintTLAB 查看TLAB信息
-XX:ResizeTLAB 自适应调整TLABRefillWasteFraction的阈值
-XX:TLABWasteTargetPercent 设置TLAB空间所占用Eden空间的百分比大小。

方法区:

-verbose:class 在程序运行的时候究竟会有多少类被加载,你可以用verbose:class来监视,在命令行输入java -verbose:class XXX (XXX为程序名)你会在控制台看到加载的类的情况。
-XX:+TraceClassLoading 动态跟踪类的加载。
-XX:+TraceClassUnLoading 动态跟踪类的卸载。
经验结论,在permsapce或者metaspace出现溢出时,可以首先考虑是否有类加载器等不停的被加载或者卸载,常见情况为:1. 使用反射不当未使用缓存,大规模操作下同样的类加载器被多次重复加载;2. 代理使用不当,例如某些设计,bean的创建非单利模式,同时使用cglib作为代理模式,请求量骤增时会出现很多通过字节码增强方式生成的类;
-Xnoclassgc 关闭CLASS的垃圾回收功能,就是虚拟机加载的类,即便是不使用,没有实例也不会回收。如果一个类20分钟还没有使用,虚拟机会卸载这个类。如果这个类再次使用,虚拟机会重新加载这个类,由于虚拟机加载类包含了IO和内存分配的操作,因此加载时会对性能有所影响。对于一般应用,这个参数对性能影响不大。
‐XX:MetaspaceSize 设置方法区的大小,也是触发GC的阈值
‐XX:MaxMetaspaceSiz 设置方法区的最大值

收集器设置

基础收集器:
-XX:+UseSerialGC 设置串行收集器(client 模式下开启,其他模式关闭)
-XX:+UseSerialOldGC 指定老年代为Serial收集器
-XX:+UseParallelGC 设置并行收集器,选择垃圾收集器为并行收集器,此配置仅对年轻代有效,即上述配置下,年轻代使用并行收集,而老年代仍旧使用串行收集。采用了多线程并行管理和回收垃圾对象,提高了回收效率,提高了服务器的吞吐量,适合于多处理器的服务器。
-XX:ParallelGCThreads=n 设置并发收集器年轻代收集方式为并行收集时,使用的CPU数
-XX:+UseParalledlOldGC 设置并行年老代收集器,采用对于老年代并行收集的策略,可以提高收集效率。JDK6.0支持对老年代并行收集。
-XX:+UseParNewGC 指定在 New Generation使用 parallel collector,是 UseParallelGC的 gc的升级版本,有更好的性能或者优点 ,可以和 CMS gc一起使用。
-XX:+AggressiveHeap 选项会检测主机的资源(内存大小、处理器数量),然后调整相关的参 数,使得长时间运行的、内存申请密集的任务能够以最佳状态运行。该选项最初是为拥有大量内存和 很多处理器的主机而设计的,但是从J2SE1.4.1以及其后继版本来看,即使是对于那些只有4颗CPU的 主机,该选项都是很有帮助的。因此,吞吐收集器(-XX:+UseParallelGC)、大小自适应 (-XX:+UseAdaptiveSizePolicy)以及本选项(-XX:+AggressiveHeap)经常结合在一起使用。要使 用本选项,主机上至少要有256M的物理内存,堆内存的最初大小是基于物理内存计算出来的,然后 会根据需要尽可能的利用物理内存。用于JVM运行于大内存模式下,JVM的堆空间至少在1G以上
-XX:MaxGCPauseMillis=n 控制最大垃圾收集停顿时间,大于0的毫秒数;
-XX:GCTimeRatio 设置垃圾收集时间占总时间的比率,0<n<100的整数;
-XX:+UseAdaptiveSizePolicy 设置此选项后,并行收集器会对于收集时间、分配比例、收集之 后 堆的空闲空间等数据进行统计分析,然后以此为依据调整新生代和旧生代的大小以达到最佳效果。此值建议使用并行收集器时,一直打开。

CMS相关:
-XX:+UseConcMarkSweepGC:设置并发收集器
-XX:MaxGCPauseMillis=n 控制最大垃圾收集停顿时间,大于0的毫秒数;
-XX:GCTimeRatio=n 设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)并发收集器设置
-XX:+CMSIncrementalMode 设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads=n 设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。
-XX:+ClassUnloading 对持久代卸载的类进行回收
-XX:+CMSClassUnloadingEnabled 使CMS收集持久代的unload的类,而不是fullgc
-XX:+CMSPermGenSweepingEnabled 使CMS收集持久代的类不引用的class,而不是fullgc。
-XX:+CMSParallelRemarkEnabled 并行标记,降低停顿
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSFullGCsBeforeCompaction=n 与UseCMSCompactAtFullCollection配对使用,使用cms会出现空间碎片,所以可根据应用本身的特性进行累计进行n次fullGC后进行一次压缩空间;源代码为:
void CMSCollector::decide_foreground_collection_type(
bool clear_all_soft_refs, bool* should_compact,
bool* should_start_over) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
assert(gch->collector_policy()->is_two_generation_policy(),
"You may want to check the correctness of the following");
if (gch->incremental_collection_will_fail(false /* don't consult_young /)) {
assert(!_cmsGen->incremental_collection_failed(),
"Should have been noticed, reacted to and cleared");
_cmsGen->set_incremental_collection_failed();
}
*should_compact =
UseCMSCompactAtFullCollection &&
((_full_gcs_since_conc_gc >= CMSFullGCsBeforeCompaction) ||
GCCause::is_user_requested_gc(gch->gc_cause()) ||
gch->incremental_collection_will_fail(true /
 consult_young */));
*should_start_over = false;
if (clear_all_soft_refs && !*should_compact) {

        if (CMSCompactWhenClearAllSoftRefs) {
        *should_compact = true;
        } else {
            *should_start_over = true;
        } // else we can continue a possibly ongoing current cycle
        }
    }

Copy

}

-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=70 与UseCMSInitiatingOccupancyOnly配对使用,如果不指定,JVM仅在第一次使用设定值,后续则自动调整;此参数表示是指设定CMS在对OLD占用率达到70%的时候开始GC过低可能引起频繁fullGC,过高可能引起promation faild;过低会引起频繁的收集,影响吞吐率;jvm源码中标准计算公式为:
void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, uintx tr) {
assert(io <= 100 && tr <= 100, "Check the arguments");
if (io >= 0) {
_initiating_occupancy = (double)io / 100.0;
} else {
_initiating_occupancy = ((100 - MinHeapFreeRatio) +
(double)(tr * MinHeapFreeRatio) / 100.0)
/ 100.0;
}
}
[注:(本文漏出的jvm源代码版本均为openjdk 1.8) 坐标:/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp],运行java -XX:+PrintFlagsFinal -version 可得知MinHeapFreeRatio值为40,CMSTriggerRatio值为80,在无设置的情况下默认值为92,建议应用设置范围为70~85之间;
-XX:ConcGCThreads 并发执行的线程数,默认值接近整个应用线程数的1/4。

G1收集器相关:
-XX:+UseG1GC 启用G1收集器
-XX:GCTimeRatio=n 设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)并发收集器设置
-XX:MaxGCPauseMillis 设置允许的最大GC停顿时间(GC pause time),这只是一个期望值,实际可能会超出,可以和年轻代大小调整一起并用来实现。默认是200ms。
-XX:G1HeapRegionSize 每个分区的大小,默认值是会根据整个堆区的大小计算出来,范围是1M~32M,取值是2的幂,计算的倾向是尽量有2048个分区数。
-XX:InitiatingHeapOccupancyPercent 一般会简写IHOP,默认是45%,这个占比跟并发周期的启动相关,当空间占比达到这个值时,会启动并发周期。如果经常出现FullGC,可以调低该值,尽早的回收可以减少FullGC的触发,但如果过低,则并发阶段会更加频繁,降低应用的吞吐。
-XX:G1NewSizePercent 年轻代最小的堆空间占比,默认是5%。
-XX:G1MaxNewSizePercent 年轻代最大的堆空间占比,默认是60%。
-XX:G1HeapWastePercent 允许的浪费堆空间的占比,默认是5%(java -XX:+PrintFlagsFinal -version | grep "G1HeapWastePercent" --col 查看)。如果并发标记可回收的空间小于5%,则不会触发MixedGC。
-XX:G1MixedGCCountTarget 一次全局并发标记之后,后续最多执行的MixedGC次数。 默认值是8.
[相关参数示意可见源代码 /hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp]

锁优化相关设置:

-XX:+UseSpining开启自旋锁(1.6 后默认开启)
-XX:PreBlockSpin=N 更改自旋锁的自旋次数,使用这个参数必须先开启自旋锁,默认的自旋次数是10次
-XX:+UseBiasedLocking 开启偏向锁(1.6后默认开启)
-XX:+UseBoundThreads 绑定所有的用户线程到内核线程。减少线程进入饥饿状态(得不到任何cpu time)的次数。

其他:

-XX:+UseCompressedOops (需要jdk1.6.0_14以上)解释器在解释字节码时,植入压缩指令(不影响正常和JVM优化后的指令顺序)。具体逻辑是,当对象被读取时,解压存入heap时进行压缩。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath={文件路径}
使用了标志-XX:+HeapDumpOnOutOfMemoryError,JVM会在遇到OutOfMemoryError时拍摄一个“堆转储快照”,并将其保存在一个文件中。
-verbose:gc
-XX:+PrintGCDetails 打印日志,同上
-XX:+PrintGCDateStamps 格式化时间戳
-XX:+DisableExplicitGC 禁止使用System.gc

猜你喜欢

转载自blog.csdn.net/weixin_42498050/article/details/106889034