JVM 的常用参数 以及 JVM参数调优
JVM 的常用参数 以及 JVM参数调优
1、常用参数
JVM的参数非常之多,这里只列举比较重要的几个,通过各种各样的搜索引擎也可以得知这些信息。
参数名称 | 含义 | 默认值 | 说明 |
-Xms | 初始堆大小 | 物理内存的1/64(<1GB) | 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制. 使用方法: |
-Xmx | 最大堆大小 | 物理内存的1/4(<1GB) | 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制 使用方法: |
-Xmn | 新生代最大值(1.4or later) |
| 注意:此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。整个堆大小=年轻代大小 + 老年代大小 + 持久代(永久代)大小.增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8 使用方法: |
-XX:NewSize | 设置年轻代大小(for 1.3/1.4) |
| 如果我们要为 新生代分配 最小256m 的内存,最大 1024m的内存我们的参数应该这样来写:
|
-XX:MaxNewSize | 年轻代最大值(for 1.3/1.4) |
|
|
-XX:PermSize | 设置持久代(perm gen)初始值 | 物理内存的1/64 | jdk1.8已废弃 |
-XX:MaxPermSize | 设置持久代最大值 | 物理内存的1/4 | jdk1.8已废弃 |
| 默认为机器的本地内存 | | // 设置 Metaspace 的初始值(jdk1.8后用于替换permSize) |
-Xss | 线程栈最大值 |
| JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.根据应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。(校长)和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:-Xss is translated in a VM flag named ThreadStackSize”一般设置这个值就可以了 使用方法: |
-XX:NewRatio | 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代) |
| -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。 |
-XX:SurvivorRatio | Eden区与Survivor区的大小比值 |
| 设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10 |
-XX:+DisableExplicitGC | 关闭System.gc() |
| 这个参数需要严格的测试 |
-XX:PretenureSizeThreshold | 对象超过多大是直接在旧生代分配 | 0 | 设置该参数,可以使大于这个值的对象直接在老年代分配,避免在Eden区和Survivor区发生大量的内存复制,该参数只对Serial和ParNew收集器有效,Parallel Scavenge并不认识该参数。 使用方法: |
-XX:ParallelGCThreads | 并行收集器的线程数 |
| 此值最好配置与处理器数目相等 同样适用于CMS |
-XX:MaxGCPauseMillis | 每次年轻代垃圾回收的最长时间(最大暂停时间) |
| 如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值. |
| 最大值15 | 15 |
|
| OOM时DUMP内存 | |
可以通过 |
| 年轻代使用Serial垃圾收集器 | |
|
-XX:+UseParallelGC | 年轻代使用Parallel Scavenge垃圾收集器 | | 开启 |
-XX:+UseParallelOldGC | 年轻代使用Parallel Scavenge收集器 | | 开启 |
-XX:+UseConcMarkSweepGC | 老年代使用CMS收集器(如果出现"Concurrent Mode Failure",会使用SerialOld收集器) | | 开启 |
-XX:+UseG1GC | 使用G1垃圾收集器 | | 使用G1垃圾收集器 |
-XX:+CollectGen0First | | | 设置FullGC时是否先YGC,默认值是false |
-Xloggc | GC日志文件路径 | | 使用方法: |
-XX:+UseGCLogFileRotation | 滚动GC日志文件,须配置Xloggc | | 滚动GC日志文件,须配置Xloggc |
-XX:GCLogFileSize=100k | | | GC文件滚动大小,需配置UseGCLogFileRotation,设置为0表示仅通过jcmd命令触发 |
-XX:+PrintGCDetails | | | GC时打印更多详细信息,默认关闭。 开启 可以通过 |
-XX:+PrintGCDateStamps | | | GC时打印时间戳信息,默认关闭 可以通过 |
-XX:+PrintTenuringDistribution | | | 打印存活实例年龄信息,默认关闭 |
-XX:+PrintGCApplicationStoppedTime | | | 打印应用暂停时间,默认关闭 |
-XX:+PrintHeapAtGC | | | GC前后打印堆区使用信息,默认关闭 |
2、JVM 堆内存调优
对JVM进行调优,主要就是堆内存那块。所有线程共享数据区大小=新生代大小 + 年老代大小 + 持久代大小(jdk8以前)。持久代一般固定大小为64m。所以java堆中增大年轻代后,将会减小年老代大小(因为老年代的清理是使用fullgc,所以老年代过小的话反而是会增多fullgc的)。此值对系统性能影响较大,Sun官方推荐配置为java堆的3/8 。
2.1、调整最大堆内存和最小堆内存
-Xmx –Xms:指定java堆最大值(默认值是物理内存的1/4(<1GB))和初始java堆最小值(默认值是物理内存的1/64(<1GB))
默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.,默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。简单点来说,你不停地往堆内存里面丢数据,等它剩余大小小于40%了,JVM就会动态申请内存空间不过会小于-Xmx,如果剩余大小大于70%,又会动态缩小不过不会小于–Xms。就这么简单
开发过程中,通常会将 -Xms 与 -Xmx两个参数配置成相同的值,其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源。
2.2、调整新生代和老年代的比值
-XX:NewRatio --- 新生代(eden+2*Survivor)和老年代(不包含永久区)的比值
例如:-XX:NewRatio=4,表示新生代:老年代=1:4,即新生代占整个堆的1/5。在Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。
2.3 、调整Survivor区和Eden区的比值
-XX:SurvivorRatio(幸存代)--- 设置两个Survivor区和eden的比值
例如:8,表示两个Survivor:eden=2:8,即一个Survivor占年轻代的1/10
2.4、 设置年轻代和老年代的大小
-XX:NewSize --- 设置年轻代大小
-XX:MaxNewSize --- 设置年轻代最大值
可以通过设置不同参数来测试不同的情况,反正最优解当然就是官方的Eden和Survivor的占比为8:1:1,然后在刚刚介绍这些参数的时候都已经附带了一些说明,感兴趣的也可以看看。反正最大堆内存和最小堆内存如果数值不同会导致多次的gc,需要注意。
总结:
根据实际事情调整新生代和幸存代的大小,官方推荐新生代占java堆的3/8,幸存代占新生代的1/10
在OOM时,记得Dump出堆,确保可以排查现场问题,通过下面命令你可以输出一个.dump文件,这个文件可以使用VisualVM或者Java自带的Java VisualVM工具。
-Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=你要输出的日志路径
一般我们也可以通过编写脚本的方式来让OOM出现时给我们报个信,可以通过发送邮件或者重启程序等来解决。
GC 调优策略中很重要的一条经验总结是这样说的:
将新对象预留在新生代,由于 Full GC 的成本远高于 Minor GC,因此尽可能将对象分配在新生代是明智的做法,实际项目中根据 GC 日志分析新生代空间大小分配是否合理,适当通过“-Xmn”命令调节新生代大小,最大限度降低新对象直接进入老年代的情况。
3、JVM的栈参数调优
3.1、 调整每个线程栈空间的大小
可以通过-Xss:调整每个线程栈空间的大小
JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
设置线程栈的大小: -XXThreadStackSize:
设置线程栈的大小(0 means use default stack size)
4、垃圾收集相关
垃圾回收器
为了提高应用程序的稳定性,选择正确的垃圾收集open in new window算法至关重要。
JVM具有四种类型的GC实现:
- 串行垃圾收集器
- 并行垃圾收集器
- CMS垃圾收集器
- G1垃圾收集器
可以使用以下参数声明这些实现:
-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+UseParNewGC
-XX:+UseG1GC
5、GC记录
为了严格监控应用程序的运行状况,我们应该始终检查JVM的垃圾回收性能。最简单的方法是以人类可读的格式记录GC活动。
使用以下参数,我们可以记录GC活动:
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=< number of log files >
-XX:GCLogFileSize=< file size >[ unit ]
-Xloggc:/path/to/gc.log