JVM技术专题深入研究JVM性能参数大全「介绍篇」
Posted 浩宇の天尚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM技术专题深入研究JVM性能参数大全「介绍篇」相关的知识,希望对你有一定的参考价值。
功能开关参数
参数 | 默认值 | 功能 |
---|---|---|
-XX:-AllowUserSignalHandlers | 限于Linux和Solaris,默认不启用 | 允许为java进程安装信号处理器,信号处理参见类:sun.misc.Signal, sun.misc.SignalHandler |
-XX:+DisableExplicitGC | 默认启用 | 禁止在运行期显式地调用System.gc() |
-XX:+FailOverToOldVerifier | Java6新引入选项,默认启用 | 如果新的Class校验器检查失败,则使用老的校验器 |
-XX:+HandlePromotionFailure | java5以前是默认不启用,java6默认启用 | 是否开启新生代收集担保 |
-XX:+UseSpinning | 对于java6来说已经默认启用了 | 是否开启自旋锁机制 |
-XX:+MaxFDLimit | 默认启用 | 设置java进程可用文件描述符为操作系统允许的最大值。 |
-XX:-RelaxAccessControlCheck | 默认不启用 | 在Class校验器中,放松对访问控制的检查,作用与reflection里的setAccessible类似 |
-XX:+ScavengeBeforeFullGC | 默认启用 | 在Full GC前触发一次Minor GC |
-XX:-UseConcMarkSweepGC | 默认不启用 | 启用CMS低停顿垃圾收集器,减少FGC的暂停时间 |
-XX:+UseGCOverheadLimit | 默认启用 | 限制GC的运行时间。如果GC耗时过长,就抛OOM |
-XX:-UseParallelGC | -server时启用,其他情况下,默认不启用 | 策略为新生代使用并行清除,年老代使用单线程Mark-Sweep-Compact的垃圾收集器 |
-XX:-UseParallelOldGC | 默认不启用 | 策略为老年代和新生代都使用并行清除的垃圾收集器 |
-XX:-UseSerialGC | -client时启用,其他情况下,默认不启用 | 使用串行垃圾收集器 |
-XX:+UseTLAB | 1.4.2以前和使用-client选项时,默认不启用,其余版本默认启用 | 启用线程本地缓存区 |
-XX:+UseThreadPriorities | 默认启用 | 使用本地线程的优先级 |
-XX:+AggressiveOpts | JDK 5 update 6后引入,但需要手动启用, JDK6默认启用 | 启用JVM开发团队最新的调优成果。例如编译优化,偏向锁,并行年老代收集等 |
-XX:+UseBiasedLocking | JDK 5 update 6后引入,但需要手动启用, JDK6默认启用 | 启用偏向锁 |
-XX:+UseFastAccessorMethods | 默认启用 | 优化原始类型的getter方法性能(get/set:Primitive Type) |
-XX:+UseStringCache | 默认开启 | 启用缓存常用的字符串。 |
性能参数
参数 | 默认值或限制 | 说明 |
---|---|---|
-XX:CompileThreshold=10000 | 1000 | 通过JIT编译器,将方法编译成机器码的触发阀值,可以理解为调用方法的次数,例如调1000次,将方法编译为机器码 |
-XX:PreBlockSpin=10 | -XX:+UseSpinning 必须先启用,对于java6来说已经默认启用了,这里默认自旋10次 | 控制多线程自旋锁优化的自旋次数 |
-XX:LargePageSizeInBytes=4m | 默认4m, amd64位:2m | 设置堆内存的内存页大小 |
-XX:MaxHeapFreeRatio=70 | 70 | GC后,如果发现空闲堆内存占到整个预估上限值的70%,则收缩预估上限值 |
-XX:MaxNewSize=size | 1.3.1 Sparc: 32m, 1.3.1 x86: 2.5m | 新生代占整个堆内存的最大值 |
-XX:MaxPermSize=64m | 5.0以后: 64 bit VMs会增大预设值的30%, 1.4 amd64: 96m, 1.3.1 -client: 32m, 其他默认 64m | Perm(俗称方法区)占整个堆内存的最大值 |
-XX:MaxPermSize=64m | 5.0以后: 64 bit VMs会增大预设值的30%, 1.4 amd64: 96m, 1.3.1 -client: 32m, 其他默认 64m | Perm(俗称方法区)占整个堆内存的最大值 |
-XX:MinHeapFreeRatio=40 | 40 | GC后,如果发现空闲堆内存占到整个预估上限值的40%,则增大上限值 |
-XX:NewRatio=2 | Sparc -client: 8, x86 -server: 8, x86 -client: 12, -client: 4 (1.3),8 (1.3.1+), x86: 12, 其他默认 2 | 新生代和年老代的堆内存占用比例, 例如2表示新生代占年老代的1/2,占整个堆内存的1/3 |
-XX:NewSize=2.125m | 5.0以后: 64 bit Vms 会增大预设值的30%, x86: 1m, x86, 5.0以后: 640k, 其他默认 2.125m | 新生代预估上限的默认值 |
-XX:SurvivorRatio=8 | Solaris amd64: 6, Sparc in 1.3.1: 25, Solaris platforms 5.0以前: 32, 其他默认 8 | Eden与Survivor的占用比例。例如8表示,一个survivor区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9?因为我们的新生代有2个survivor,即S0和S1。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10 |
-XX:TargetSurvivorRatio=50 | 50 | 实际使用的survivor空间大小占比。默认是50%,最高90% |
Trace跟踪参数
参数 | 默认值或限制 | 说明 |
---|---|---|
-verbose:gc -XX:+printGC | 打印GC的简要信息 | 搭配使用最好 |
-XX:+PrintHeapAtGC | 关闭 | 打印GC详细信息当发生GC |
-XX:+PrintGCDetails | 关闭 | 打印GC详细信息 |
-XX:+PrintGCTimeStamps | 关闭 | 打印CG发生的时间戳 |
-Xloggc:log/gc.log | 指定GC log的位置,以文件输出 | |
XX:+TraceClassLoading | 监控类的加载 | 监控类的加载 |
-XX:+PrintClassHistogram | 打印类的信息 | 打印类的信息 |
-XX:-CITime | 打印发费在JIT编译上的时间 |
堆分配参数
参数 | 默认值或限制 | 说明 |
---|---|---|
-Xmx –Xms | 分别是1/4 和 1/64 | 指定最大堆和最小堆 |
-Xmn | 关闭 | 设置新生代大小 |
-XX:NewRatio | 2 | 新生代(eden+2*s)和老年代(不包含永久区)的比值 ,4,表示新生代:老年代=1:4,即新生代占整个堆的1/5 |
-XX:SurvivorRatio(幸存代) | 8 | 设置两个Survivor区和eden的比值 |
-XX:+HeapDumpOnOutOfMemoryError | OOM时导出堆到文件 根据这个文件,我们可以看到系统dump时发生了什么 | |
-XX:HeapDumpPath=./java_pid.hprof | 导出OOM的路径 | |
-XX:PermSize -XX:MaxPermSize | 设置永久区的初始空间和最大空间。也就是说,jvm启动时,永久区一开始就占用了PermSize大小的空间,如果空间还不够,可以继续扩展,但是不能超过MaxPermSize,否则会OOM。 | |
-XX:OnOutOfMemoryError=”;” | -XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat %p //p代表的是当前进程的pid ,当发生OOM的时候进行调用脚本等功能 | |
-XX:OnError=”; | 当发生错误时执行用户指定的命令 | |
-XX:-PrintTenuringDistribution | 打印分配内存时候的年龄 | |
-XX:+UseCompressedOops | 启动压缩机制 | |
-XX:InitialTenuringThreshold=7 | 设置初始的对象在新生代中最大存活次数 | |
-XX:MaxTenuringThreshold= | 设置对象在新生代中最大的存活次数,最大值15,并行回收机制默认为15,CMS默认为4 |
栈的分配参数
-Xss128K 设置栈空间的大小。通常只有几百K 决定了函数调用的深度 每个线程都有独立的栈空间 局部变量、参数 分配在栈上
调优总结
GC垃圾回收流程
数据会首先分配到Eden区当中(当然也有特殊情况,如果是大对象那么会直接放入到老年代(大对象是指需要大量连续内存空间的java对象),当Eden没有足够空间的时候就会触发jvm发起一次Minor GC。如果对象经过一次Minor GC还存活,并且又能被Survivor空间接受,那么将被移动到Survivor空间当中。并将其年龄设为1,对象在Survivor每熬过一次Minor GC,年龄就加1,当年龄达到一定的程度(默认为15)时,就会被晋升到老年代 中了,当然晋升老年代的年龄是可以设置的。
年轻代大小选择
- 响应时间优先的应用 :尽可能设大年轻代大小,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对象。
- 吞吐量优先的应用:尽可能的设置大,可能到达GBit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。
年老代大小选择
- 响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。
最优化的方案,一般需要参考以下数据获得:
- 并发垃圾收集信息
- 持久代并发收集次数
- 传统GC信息
- 花在年轻代和年老代回收上的时间比例
- 减少年轻代和年老代花费的时间,一般会提高应用的效率
-
吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。
-
较小堆引起的碎片问题:因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。
当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是,当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。(此时还有可能会存在Concurrent Prometion failure)
如果出现“碎片”,可能需要进行如下配置:
- -XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
- -XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩
- -XX:MaxHeapFreeRatio=30
以上是关于JVM技术专题深入研究JVM性能参数大全「介绍篇」的主要内容,如果未能解决你的问题,请参考以下文章