JVM性能调优2:JVM性能调优参数整理

时间:2023-01-21 20:25:10
本系列包括:
 

序号 参数名 说明 JDK 默认值 使用过
1 JVM执行模式        
2 -client
-server
设置该JVM运行与Client 或者Server Hotspot模式,这两种模式从本质上来说是在JVM中运行不同的JIT(运行时编译模块)代码,并且两者在JVM内部的接口是一致的。客户端模式优化的是系统启动时间更快,而服务端模式的优化则更关注与系统的整体性能。一般来说Client选项用于GUI的应用,Server选项多用于后台服务器应用。
另外两者在编译策略、垃圾收集策略、堆使用上也有所不同
   
3 -d32
-d64
指明该Java VM是运行与32位环境还是64位环境,默认是运行在32位环境下的,如果是配置了64位模式则需要操作系统也必须是64位的,当然CPU更需要是64位的。另外如果我们选择了-server参数,则就暗含了64位模式。   默认32模式  
4 -hotspot 在Hotspot类型的JVM中缺省使用,缺省为Client Hotspot模式。   默认client模式  
5 -Xmixed JVM执行模式的设置参数,混合模式即支持Hotspot即时编译的运行模式.
支持Hotspot的JVM缺省都是运行于混合模式的。
  默认混合模式  
  -Xcomp JVM优先以编译模式运行,不能编译的,以解释模式运行。      
6 -Xint 设置JVM的执行模式为解释执行模式,纯解释执行的JVM对多数应用来说基本上时没有意义的,仅仅可能会在一些嵌入式系统中应用      
7 内存分配相关参数        
8 -Xms<size> 设置JVM启动时初始内存堆的大小 1.6 物理内存的1/64.
9 -Xmx<size> 设置JVM启动后动态申请堆内存的最大堆空间 1.6 MIN(物理内存的1/4,1G)
10 -Xmn<size> 为新生代分配的内存大小。   和cpu核数相关,建议1core对应512M,不超过1G。
11 -Xss<size> 设置JVM线程栈的空间最大值。 1.6 当设置值小于64K时,用默认值。
12 -XX:ThreadStackSize=512 每个线程栈大小(K),等于0时表示使用缺省值   Sparc: 512K,Solaris Intel: 256K,Sparc 64bit: 1024 其他的都为 0  
13 -XX:NewRatio=2 新生代内存容量与老生代内存容量的比例。
Ratio of new/old generation sizes. The default value is 2.
1.6 Client模式默认8,Server模式:2
14 -XX:MaxNewSize=size Maximum size of new generation (in bytes). Since 1.4, MaxNewSize is computed as a function of NewRatio. [1.3.1 Sparc: 32m; 1.3.1 x86: 2.5m.]      
15 -XX:NewSize=2m 新生代预估默认值。Default size of new generation (in bytes) [5.0 and newer: 64 bit VMs are scaled 30% larger; x86: 1m; x86, 5.0 and older: 640k] 1.6 2228K  
16 -XX:SurvivorRatio=64 存活区和eden区所占的比率:2:64。
Ratio of eden/survivor space size.
1.6 32
17 -XX:PermSize=256m 为持久代分配的初始化内存空间。      
18 -XX:MaxPermSize=256m 为持久代分配的最大内存空间。   client/server:64M
19 -XX:MaxTenuringThreshold=30 每次垃圾收集在新生代之间Copy的次数,超过该次数则移至Old区。
Maximum value for tenuring threshold. The default value is 15.
  The default value is 15 for the parallel collector and is 4 for CMS.
20 -XX:TargetSurvivorRatio=50 该值是一个百分比,控制允许使用的生存区空间的比例。该参数设置较大的话可提高对survivor空间的使用率。   默认值是50。即占到50%,则执行Copy策略。
21 -XX: PretenureSizeThreshold=64K 当申请内存的对象超过该值时,直接在old区分配。   默认值是0,即所有的对象都在Eden区分配。  
22 -XX:MaxHeapFreeRatio=size JVM中堆空间的最大预估值空闲百分比。GC进行垃圾收集时后,如果预估值堆空闲空间超过预定值,收缩预估值内存。   默认值70
23 -XX:MinHeapFreeRatio=size JVM中堆空间的最小预估值空闲百分比。GC进行垃圾收集后,堆空间不得低于预定值,增加分配的内存。   默认值40
  -XX:MaxDirectMemorySize=size 直接内存最大值。即NIO进行操作时,可以分配的最大缓存值,默认和heap最大值一致。   默认和heap最大值一致。  
24 JVM优化        
25 -XX:CompileThreshold=10000 设置方法是否进行即时编译的调用次数的下限值。调用次数超过设定值,进行JIT编译。   -server选项的缺省值为10000-client选项的缺省值为1500
  -XX:+BackgroundCompilation 后台启用jit编译      
26 -XX:-CITime 设置Hotspot的一次即时编译所需要的最大时间      
27 -XX:+AggressiveOpts 启用激进的编译优化   JDK 5 update 6后引入,但需要手动启用。
JDK6默认启用。
 
28 -XX:+UseFastAccessorMethods 原始类型的快速优化,get,set方法转成本地代码。      
29 -XX:+DoEscapeAnalysis 增加逃逸分析。如果对象的指针未出创建者的方法体,该对象在线程栈内直接分配空间。 1.6    
30 -XX:+DisableExplicitGC 屏蔽程序主动垃圾收集的函数system.gc()    
31 -XX:FreqInlineSize=size 限制经常使用的动态编译的函数的虚拟机指令的最大数量,       
32 -XX:+UseLargePages 启用大内存分页。注意操作系统需支持。
关联参数:-XX:LargePageSizeInBytes=4m
     
33 -XX:LargePageSizeInBytes=4m 设置堆内存的内存页大小。   默认4K。  
34 -XX:+UseBiasedLocking 启用偏向锁。   JDK 5 update 6后引入,但需要手动启用。
JDK6默认启用。
 
35 -XX:+UseSpinning 启用多线程自旋锁优化。
自旋锁优化原理
大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意。
原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖操作系统互斥(mutex)来实现的。
互斥是一种会导致线程挂起,并在较短的时间内又必须重新调度回原线程的,较为消耗资源的操作。
为了避免进入OS互斥,Java6的开发者们提出了自旋锁优化。
自旋锁优化的原理是在线程进入OS互斥前,通过CAS自旋一定的次数来检测锁的释放。
如果在自旋次数未达到预设值前锁已被释放,则当前线程会立即持有该锁。
  java1.4.2和1.5需要手动启用, java6默认已启用  
36 -XX:PreBlockSpin=10 控制多线程自旋锁优化的自旋次数。(什么是自旋锁优化?见 -XX:+UseSpinning 处的描述)
关联选项:
-XX:+UseSpinning
  java6来说已经默认启用了,这里默认自旋10次  
37 -XX:+UseSplitVerifier 使用新的Class类型校验器 。
新Class类型校验器有什么特点?
新Class类型校验器,将老的校验步骤拆分成了两步:
1,类型推断。
2,类型校验。
新类型校验器通过在javac编译时嵌入类型信息到bytecode中,省略了类型推断这一步,从而提升了classloader的性能。
Classload顺序(供参考)
load -> verify -> prepare -> resove -> init
关联选项:
-XX:+FailOverToOldVerifier
  java5默认不启用

java6默认启用
 
38 -XX:+FailOverToOldVerifier 如果新的Class校验器检查失败,则使用老的校验器。
为什么会失败?
因为JDK6最高向下兼容到JDK1.2,而JDK1.2的class info 与JDK6的info存在较大的差异,所以新校验器可能会出现校验失败的情况。
关联选项:
-XX:+UseSplitVerifier
  Java6新引入选项,默认启用
 
39 -XX:+HandlePromotionFailure 关闭新生代收集担保。
在一次理想化的minor gc中,Eden和First Survivor中的活跃对象会被复制到Second Survivor。然而,Second Survivor不一定能容纳下所有从E和F区copy过来的活跃对象。为了确保minor gc能够顺利完成,GC需要在年老代中额外保留一块足以容纳所有活跃对象的内存空间。这个预留操作,就被称之为新生代收集担保(New Generation Guarantee)。如果预留操作无法完成时,仍会触发major gc(full gc)。
为什么要关闭新生代收集担保?
因为在年老代中预留的空间大小,是无法精确计算的。为了确保极端情况的发生,GC参考了最坏情况下的新生代内存占用,即Eden+First Survivor。这种策略无疑是在浪费年老代内存,从时序角度看,还会提前触发Full GC。为了避免如上情况的发生,JVM允许开发者手动关闭新生代收集担保。在开启本选项后,minor gc将不再提供新生代收集担保,而是在出现survior或年老代不够用时,抛出promotion failed异常。
  java5以前是默认不启用,java6默认启用
 
40 -XX:+UseTLAB 启用线程本地缓存区(Thread Local)。   1.4.2以前和使用-client选项时,默认不启用,其余版本默认启用  
41 -XX:+UseThreadPriorities 使用本地线程的优先级。   默认启用  
42 -XX:-UseLWPSynchronization 使用操作系统提供的轻量级线程LWP同步来代替基于Java虚拟机的线程的同步   限于solaris,默认启用  
43 -XX:+UseBoundThreads 绑定所有的用户线程到内核线程。
减少线程进入饥饿状态(得不到任何cpu time)的次数。
  限于solaris,默认启用  
44 垃圾收集器设置        
45 -XX:+UseSerialGC 设置串行收集器    
46 -XX:+UseParallelGC 选择垃圾收集器为并行收集器,此配置仅对年轻代有效,即上述配置下,年轻代使用并行收集,而老年代仍旧使用串行收集。采用了多线程并行管理和回收垃圾对象,提高了回收效率,提高了服务器的吞吐量,适合于多处理器的服务器。    
47 -XX:+UseParNewGC 指定在 New Generation使用 parallel collector, UseParallelGC gc的升级版本 ,有更好的性能或者优点 ,可以和 CMS gc一起使用    
48 -XX:+UseParallelOldGC 采用对于老年代并行收集的策略,可以提高收集效率。JDK6.0支持对老年代并行收集。    
49 -XX:+UseConcMarkSweepGC 指定在老年代使用 concurrent cmark sweep gcgc thread app thread并行 ( init-mark remark pause app thread)app pause时间较短 ,适合交互性强的系统 , web server。它可以并发执行收集操作,降低应用停止时间,同时它也是并行处理模式,可以有效地利用多处理器的系统的多进程处理。新生代默认使用:parnew   使用此垃圾收集器是,sun建议NewRatio=4  
50 -XX:+CMSIncrementalMode 设置为增量模式。适用于单CPU情况      
51 -XX:+ClassUnloading 对持久代卸载的类进行回收      
52 -XX:+CMSClassUnloadingEnabled 使CMS收集持久代的unload的类,而不是fullgc      
53 -XX:+CMSPermGenSweepingEnabled 使CMS收集持久代的类不引用的class,而不是fullgc   1.JDK 1.6 32位下不可用。
2.JDK 1.5 64位下可用。
 
73 -XX:+UseAdaptiveSizePolicy 设置此选项后,并行收集器会对于收集时间、分配比例、收集之 后 堆的空闲空间等数据进行统计分析,然后以此为依据调整新生代和旧生代的大小以达到最佳效果。此值建议使用并行收集器时,一直打开。   适合吞吐量优先的垃圾收集器。
使用sun jdk(1.6.30以上到1.7的全部版本已经确认有该问题,jdk8修复,其他版本待验证
74 -XX:+AggressiveHeap 选项会检测主机的资源(内存大小、处理器数量),然后调整相关的参 数,使得长时间运行的、内存申请密集的任务能够以最佳状态运行。该选项最初是为拥有大量内存和 很多处理器的主机而设计的,但是从J2SE1.4.1以及其后继版本来看,即使是对于那些只有4颗CPU的 主机,该选项都是很有帮助的。因此,吞吐收集器(-XX:+UseParallelGC)、大小自适应 (-XX:+UseAdaptiveSizePolicy)以及本选项(-XX:+AggressiveHeap)经常结合在一起使用。要使 用本选项,主机上至少要有256M的物理内存,堆内存的最初大小是基于物理内存计算出来的,然后 会根据需要尽可能的利用物理内存。用于JVM运行于大内存模式下,JVM的堆空间至少在1G以
上。与-Xms、-Xmx不同时使用,慎用!会导致JVM极度消耗内存
  适合吞吐量优先的垃圾收集器。 是,在基建的性能调优时用过,并没有显示出出色的性能。
54 垃圾收集器相关参数        
55 -XX:+ScavengeBeforeFullGC 并收集,在Full GC前触发一次Minor GC。   默认启用  
57 -XX:+CMSParallelRemarkEnabled  尽量减少 mark的时间。     该参数未验证。
  -XX:CMSScavengeBeforRemark 并发收集,在remark之前,启动次收集。      
56 -XX:+UseGCOverheadLimit 限制GC的运行时间。如果GC耗时过长,就抛OOM。   默认启用  
58 -XX:CMSFullGCsBeforeCompaction=10 由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生碎片,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。发生多少次CMS Full GC,这个参数最好不要设置,因为要做compaction的话,也就是真正的Full GC是串行的,非常慢,让它自己去决定什么时候需要做compaction   配合并发垃圾收集器。  
59 -XX:+UseCMSCompactAtFullCollection 打开对老年代的压缩。可能会影响性能,但是可以消除碎片,FULL GC的时候,压缩内存, CMS是不会移动内存的,因此,这个非常容易产生碎片,导致内存不够用,因此,内存的压缩这个时候就会被启用。增加这个参数是个好习惯。   配合并发垃圾收集器。  
60 -XX:CMSInitiatingOccupancyFraction 说明老年代到百分之多少满的时候开始执行对老年代的并发垃圾回收(CMS),这个参数设置有很大技巧,基本上满足公式:
(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn
时就不会出现promotion failed。在我的应用中Xmx6000Xmn500,那么Xmx-Xmn5500兆,也就是老年代有5500兆,CMSInitiatingOccupancyFraction=90说明老年代到90%满的时候开始执行对老年代的并发垃圾回收(CMS),这时还剩10%的空间是5500*10%=550兆,所以即使Xmn(也就是年轻代共500兆)里所有对象都搬到老年代里,550兆的空间也足够了,所以只要满足上面的公式,就不会出现垃圾回收时的promotion failed
如果按照Xmx=2048,Xmn=768的比例计算,则CMSInitiatingOccupancyFraction的值不能超过40,否则就容易出现垃圾回收时的promotion failed
  jdk:1.5配合并发垃圾收集器。默认是68%。
JDK 1.6 默认是92%。(太高,建议修改为80%)。
 
61 -XX:+UseCMSInitiatingOccupancyOnly 是否仅仅按照指定比例启动CMS收集,默认为false。指示只有在老年代在使用了初始化的比例后 concurrent collector 启动收集。
配合:,CMSInitiatingOccupancyFraction参数使用。
  默认false  
  -XX:CMSScheduleRemarkEdenSizeThreshold Eden区域多大的时候开始触发remark,默认是2M   默认是2M  
  -XX:CMSScheduleRemarkEdenPenetration Eden区域多大的时候开始出发remarkeden使用量超过百分比多少的时候触发,默认是50%   默认是50%。  
  -XX:CMSMaxAbortablePrecleanTime 但是如果长期不做remark导致old做不了,可以设置超时,这个超时默认是5秒,超过5秒钟做remark;设置preclean步骤的超时时间,单位为毫秒。   默认5秒  
  -XX:CMSInitiatingPermOccupancyFraction 持久代内存达到多是,进行垃圾收集。      
69 -XX:ConcGCThreads=n Number of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running.   配合并发垃圾收集器。
 (ParallelGCThreads + 3)/4) 

ParallelGCThreads是年轻代的并行收集线程数
JDK 32位 1.6下不可用。
  -XX:ParallelCMSThreads 同上-XX:ConcGCThreads=n      
70 -XX:MaxGCPauseMillis=<N> 指定垃圾回收时的最长暂停时间。<N>为毫秒.如果指定了此值的话,堆大小和垃圾回收相关参数会进行调整以达到指定值。设定此值可能会减少应用的吞吐量。   适合吞吐量优先的垃圾收集器。  
71 -XX:GCTimeRatio=<N> 为垃圾回收时间与非垃圾回收时间的比值.公式为1:(1+N)。例如,-XX:GCTimeRatio=19时,表示5%的时间用于垃圾回收。默认情况为99,即1%的时间用于垃圾回收。   适合吞吐量优先的垃圾收集器。
默认值:1%
 
  •-XX:+CMSConcurrentMTEnabled 在并发阶段利用多核。      
72 -XX:ParallelGCThreads=8 配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
Sets the number of threads used during parallel phases of the garbage collectors. The default value varies with the platform on which the JVM is running.
  并行垃圾收集器配套使用。
ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8);
在cms垃圾收集中:
指定在stop-the-world过程中,并行线程的个数,默认cpu个数。
 
75 -Xnoincgc 在垃圾收集中不使用火车算法      
76 -Xincgc 在垃圾收集中使用火车算法,降低暂停时间。注意会占用10%左右的CPU资源。   适合低停顿垃圾收集器。  
62 -XX:+CMSIncrementalMode 在并发垃圾收集器中,使用增量模式。默认为不使用。 1.5 配合并发垃圾收集器。
默认不启用
以下绿色表示增量收集,适用于单CPU情况。Sun不推荐使用
63 -XX:+CMSIncrementalPacing  This flag enables automatic adjustment of the incremental mode duty cycle based on statistics collected while the JVM is running. 1.5 配合并发垃圾收集器。
默认不启用
 
64 -XX:CMSIncrementalDutyCycle=<N> This is the percentage (0-100) of time between minor collections that the concurrent collector is allowed to run. If CMSIncrementalPacing is enabled, then this is just the initial value. 1.5 配合并发垃圾收集器。
默认50
 
65 -XX:CMSIncrementalDutyCycleMin=<N> This is the percentage (0-100) which is the lower bound on the duty cycle when CMSIncrementalPacing is enabled. 1.5 配合并发垃圾收集器。
10
 
66 -XX:CMSIncrementalSafetyFactor=<N> This is the percentage (0-100) used to add conservatism when computing the duty cycle 1.5 配合并发垃圾收集器。
10
 
67 -XX:CMSIncrementalOffset=<N> This is the percentage (0-100) by which the incremental mode duty cycle is shifted to the right within the period between minor collections. 1.5 配合并发垃圾收集器。
0
 
68 -XX:CMSExpAvgFactor=<N> This is the percentage (0-100) used to weight the current sample when computing exponential averages for the concurrent collection statistics 1.5 配合并发垃圾收集器。
25
 
77 调试选项        
78 -XX:-CITime 打印JIT编译器编译耗时。   1.4引入。
默认启用
 
79 -XX:HeapDumpPath=./java_pid<pid>.hprof 堆内存快照的存储文件路径。文件名一般为
java_<pid>_<date>_<time>_heapDump.hprof
  不启用  
80 -XX:+HeapDumpOnOutOfMemoryError 在OOM时,输出一个dump.core文件到   1.4.2 update12 和 5.0 update 7 引入。
默认不启用
 
81 -XX:ErrorFile=./hs_err_pid<pid>.log   1.6 如果JVM crashed,将错误日志输出到指定文件路径。  
  -verbose:gc 输出垃圾回收信息和-Xloggc:path配合使用      
  -Xloggc:filename
-XX:GCLogFileSize=5M
gc日志输出文件;日志文件分隔,每5M分隔一个文件。      
82 -XX:+PrintCompilation 往stdout打印方法被JIT编译时的信息。
例如:
1
       java.lang.String::charAt (33 bytes)
  不启用  
83 -XX:+PrintGC 开启GC日志打印。
打印格式例如:
[Full GC 131115K->7482K(1015808K), 0.1633180 secs]
  不启用  
84 -XX:+PrintGCDetails 打印GC回收的细节。
打印格式例如:
[Full GC (System) [Tenured: 0K->2394K(466048K), 0.0624140 secs] 30822K->2394K(518464K), [Perm : 10443K->10443K(16384K)], 0.0625410 secs] [Times: user=0.05 sys=0.01, real=0.06 secs]
  不启用  
85 -XX:+PrintGCTimeStamps 打印GC停顿耗时。
打印格式例如:
2.744: [Full GC (System) 2.744: [Tenured: 0K->2441K(466048K), 0.0598400 secs] 31754K->2441K(518464K), [Perm : 10717K->10717K(16384K)], 0.0599570 secs] [Times: user=0.06 sys=0.00, real=0.06secs]
  不启用  
86 -XX:+PrintTenuringDistribution 打印对象的存活期限信息。
打印格式例如:
[GC
Desired survivor size 4653056 bytes, new threshold 32 (max 32)
- age 1: 2330640 bytes, 2330640 total
- age 2: 9520 bytes, 2340160 total
204009K->21850K(515200K), 0.1563482 secs]
Age1 2表示在第1和2次GC后存活的对象大小。
  不启用  
87 -XX:+TraceClassLoading 打印class装载信息到stdout。记Loaded状态。   不启用  
88 -XX:+TraceClassLoadingPreorder 按class的引用/依赖顺序打印类装载信息到stdout。不同于 TraceClassLoading,本选项只记 Loading状态。 1.4.2 不启用  
89 -XX:+TraceClassUnloading 打印class的卸载信息到stdout。记Unloaded状态。   不启用  
90 -XX:+TraceClassResolution 打印所有静态类,常量的代码引用位置。用于debug。
例如:
RESOLVE java.util.HashMap java.util.HashMap$Entry HashMap.java:209
说明HashMap类的209行引用了静态类 java.util.HashMap$Entry
1.4.2 不启用  
91 -XX:+TraceClassUnloading 打印class的卸载信息到stdout。记Unloaded状态。   不启用  
92 -XX:+TraceLoaderConstraints 打印class的装载策略变化信息到stdout。
例如:
[Adding new constraint for name: java/lang/String, loader[0]: sun/misc/Launcher$ExtClassLoader, loader[1]: <bootloader> ]
装载策略变化是实现classloader隔离/名称空间一致性的关键技术。
1.6 不启用  
93 -XX:+PerfSaveDataToFile 当java进程因OOM或crashed被强制终止后,生成一个堆快照文件(什么是堆内存快照? 见 -XX:HeapDumpPath 处的描述)。   不启用