java gc生产环境实践

基于真实环境的gc配置,得出的gc性能调优配置

java gc生产环境实践

线上命令

小内存应用命令

生产环境内存4g.一句话版,打开了gc日志,打开了oom后的堆栈文件,配置了cms并发垃圾回收机制,设置80%阈值时候回收,启动永久带来及回收,元数据最大上线为380m

java -verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=java.hprof -XX:ErrorFile=java_error.log -Djava.awt.headless=true -DLOG_HOME=app_log -Dapp.log.dir=/data/program/logs/com.wacai.portal/antifraud-service/app_log -Dserver.tomcat.access-log-enabled=true -Dserver.tomcat.basedir=/data/program/com.wacai.portal/antifraud-service -Dmanagement.port=-1 -Dendpoints.shutdown.enabled=true -Dshell.telnet.enabled=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Xms2g -Xmx2g -XX:MetaspaceSize=38m -XX:MaxMetaspaceSize=380m -Djava.security.egd=file:/dev/./urandom -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=20 -XX:GCLogFileSize=500m -XX:NewSize=600m -XX:MaxNewSize=750m -XX:+UseConcMarkSweepGC -XX:CMSMaxAbortablePrecleanTime=5000 -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly -Dlogging.config=./config/logback.xml -jar app.jar

大内存应用

设置大内存为32g。回收阈值从80下调到75,打开AlwaysPreTouch,提前把内存分配给Jvm,让jvm可以顺畅访问内存,DisableExplicitGC禁止代码显示调用gc。

/java -Xms32g -Xmx32g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -server -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -Djdk.io.permissionsUseCanonicalPath=true -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j.skipJansi=true -XX:+HeapDumpOnOutOfMemoryError -Des.path.home=/data/program/data-es/elasticsearch-5.4.1 -cp /data/program/data-es/elasticsearch-5.4.1/lib/* org.elasticsearch.bootstrap.Elasticsearch -d

gc配置信息详解

  • -XX:+PrintGCDetails 输出gc详细信息
  • -XX:+PrintGCDateStamps 垃圾回收统计信息
  • -XX:+HeapDumpOnOutOfMemoryError oom的时候dump heap文件
  • -XX:HeapDumpPath=java.hprof dump的heap文件
  • -XX:ErrorFile=java_error.log
  • -XX:MaxMetaspaceSize=380m metaspace最大空间
  • -XX:+UseGCLogFileRotation :打开gc日志循环
  • -XX:NumberOfGCLogFiles=20 设置gc日志文件数量
  • -XX:GCLogFileSize=500m gc日志最大大小
  • -XX:NewSize=600m 设置年轻大初始大小
  • -XX:MaxNewSize=750m 新生代最大可分配内存
  • -XX:+UseConcMarkSweepGC 并发标记清除(CMS)收集器。。CMS收集器通过多线程并发进行垃圾回收,尽量减少垃圾收集造成的停顿。
  • -XX:CMSMaxAbortablePrecleanTime=5000 设置cms preclean这一步的超时时间为5000ms,
  • -XX:CMSClassUnloadingEnabled cms垃圾回收对永久带的class unloading也生效
  • XX:CMSInitiatingOccupancyFraction=80 占比达到80%的时候触发垃圾回收机制
  • -XX:+UseCMSInitiatingOccupancyOnly 关闭动态检查机制,如果不关闭,cms默认会根据历史记录预测老年代需要多久回收一次内存,cms根据自己的预测执行
  • AlwaysPreTouch 提前分配内存,大内存应用时很有用。

G1GC

G1GC是jdk9的默认垃圾回收机制。但在大内存的场景下,g1gc在jdk8下也有不错的表现。G1GC把堆内存进行了分区,默认分1024个区,巨型对象会有专门的Humongous分区,如果一个分区放不下,甚至会给它安全连续的内存分区。此处略过1万字。