JVM的关键系统参数介绍和详细配置( 四 )


-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGDIR}/
但在容器环境下,输出4G的HeapDump,在普通硬盘上会造成20秒以上的硬盘IO跑满,也是个十足的恶邻,影响了同一宿主机上所有其他的容器 。
 
3.3 GC日志JDK9完全不一样了,这里还是写JDK7/8的配置 。
1.基本配置
-Xloggc:/dev/shm/gc-myApp.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails
有人担心写GC日志会影响性能,但测试下来实在没什么影响,GC问题是Java里最常见的问题,没日志怎么行 。
后来又发现如果遇上高IO的情况,GC时操作系统正在flush pageCache 到磁盘的话,也可能导致GC log文件被锁住,从而让GC结束不了 。所以把它指向了/dev/shm 这种内存中文件系统,避免这种停顿,详见《Eliminating Large JVM GC Pauses Caused by Background IO Traffic》
用PrintGCDateStamps而不是PrintGCTimeStamps,打印可读的日期而不是时间戳 。
2. -XX:+PrintGCApplicationStoppedTime
这是个非常非常重要的参数,它的名字没起好,它除了打印清晰的完整的GC停顿时间外,还可以打印其他的JVM停顿时间,比如取消偏向锁,class 被agent redefine,code deoptimization等等,有助于发现一些原来没想到的问题,建议也加上 。如果真的发现了一些不知是什么的停顿,需要打印安全点日志找原因 。
3. -XX:+PrintGCCause
打印产生GC的原因,比如AllocationFailure什么的,在JDK8已默认打开,JDK7要显式打开一下 。
4. -XX:+PrintPromotionFailure
打开了就知道是多大的新生代对象晋升到老生代失败从而引发Full GC时的 。
5. GC日志滚动与备份
GC日志默认会在重启后清空,有人担心长期运行的应用会把文件弄得很大,所以"-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M"的参数可以让日志滚动起来 。但真用起来重启后的文件名太混乱太让人头痛,GC日志再大也达不到哪里去,所以我们没有加滚动,并且自行在启动脚本里对旧日志做备份 。
 
3.4 安全点日志如果GC日志里有非GC的JVM停顿时间,你得打出安全点日志来知道详情,详见《 JVM的Stop The World,安全点,黑暗的地底世界》
-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 -XX:+UnlockDiagnosticVMOptions -XX:-DisplayVMOutput -XX:+LogVMOutput -XX:LogFile=/dev/shm/vm-myapp.log
3.5 JMX

 
-Dcom.sun.management.jmxremote.port=7001 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1
以上设置,只让本地的Zabbix之类监控软件通过JMX监控JVM,不允许远程访问 。
如果应用忘记了加上述参数,又不想改参数重启服务,可以用VJTools的vjmxcli来救急,它能通过PID直接连入目标JVM打开JMX 。
 
 
 
【JVM的关键系统参数介绍和详细配置】


推荐阅读