你应该在生产环节熟悉的Java VM/JVM选项配置

14-11-14 banq
    

这篇文章总结了Java虚拟机在面向Web服务器的生产环境中的配置。

Java 8以前版本:

Java < 8
    -server
    -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
    -XX:PermSize=<perm gen size>[g|m|k] -XX:MaxPermSize=<perm gen size>[g|m|k]
    -Xmn<young size>[g|m|k]
    -XX:SurvivorRatio=<ratio>
    -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
    -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
    -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
    -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
    -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
    -Dsun.net.inetaddr.ttl=<TTL in seconds>
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
    -Djava.rmi.server.hostname=<external IP>
    -Dcom.sun.management.jmxremote.port=<port> 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false
<p>

Java以后版本

Java >= 8
    -server
    -Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
    -XX:MaxMetaspaceSize=<metaspace size>[g|m|k]
    -Xmn<young size>[g|m|k]
    -XX:SurvivorRatio=<ratio>
    -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
    -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
    -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
    -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
    -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
    -Dsun.net.inetaddr.ttl=<TTL in seconds>
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
    -Djava.rmi.server.hostname=<external IP>
    -Dcom.sun.management.jmxremote.port=<port> 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false
<p>

下面逐个解释如下:

-server 是配置成服务器,对于x64已经隐含激活。

-Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]

避免动态对Heap大小调整,规定最小和最大的heap大小。

-XX:PermSize=<perm gen size>[g|m|k] -XX:MaxPermSize=<perm gen size>[g|m|k]

对于永生代规定大小,避免动态调整损耗,但是不适合Java >= 8.

-XX:MaxMetaspaceSize=<metaspace size>[g|m|k]

Java VM 8 缺省的Metaspace是不限制,考虑到系统安全稳定性,设置一个数字限制。

-Xmn<young size>[g|m|k]

显式定义年轻态大小。

-XX:SurvivorRatio=<ratio>

survivour空间相对eden的大小。

-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled

对于服务器应用响应时间很重要,并发垃圾收集是很适合Web应用,但是不幸G1还没有为生产环境准备好,这样我们得使用Concurrent Mark-Sweep 收集器(CMS)

-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>

缺省的 CMS GC使用的启发式规则触发垃圾回收,这会让GC不太能预测,一般直至老生代空间被几乎占满后才会启动垃圾回收,Initiating设置能够使得在老生代变满之前完成回收,避免Full GC (这就意味着整个应用程序暂停无响应stop-the-world pause). -XX:+UseCMSInitiatingOccupancyOnly 阻止使用启发式规则 -XX:CMSInitiatingOccupancyFraction 通过JVM应该在什么时候启动触发回收,它会在heap中创建一个buffer,这个缓冲当CMS工作时能用数据填充,其内存被消耗的速度百分比可衡量老生代生产环境中的消耗。这个百分比数值应该小心选择,太小CMS太频繁,太大CMS启动频率太少,并发模式可能会失败。

-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark

指导垃圾回收机制在进行Full GC和CMS remark phase之前收集年轻态。其结果是提升性能,因为在年轻态和老态之间不存在检查引用。

剩余几个参数不是非常重要,可点击标题参考英文原文。