CUSTOM_JVM_ONLINE=" -server
-Dfile.encoding=UTF-8
-Dsun.jnu.encoding=UTF-8
-Djava.net.preferIPv6Addresses=false
-Djava.io.tmpdir=/tmp
-Duser.timezone=GMT+08
-Xmx4g//堆空间的最大内存 堆空间内存 = 年轻代内存 + 年老代内存 + 元空间内存
-Xms4g//堆空间的初始内存
-XX:MetaspaceSize=256m//该值并不是元空间初始大小,是不断动态变化的,直到元空间内存大小到达MetaspaceSize后,会发生首次fullGC
-XX:MaxMetaspaceSize=512m//元空间发生GC的阈值不断动态变化,直到MaxMetaspaceSize后不再变化,该值可理解为最大的元空间大小
-XX:SurvivorRatio=8//意思是S区与Eden空间的比值为2:8,1个S区占年轻代的1/10
-XX:NewRatio=4//表示年轻代与年老代的比值为1:4
-XX:+HeapDumpOnOutOfMemoryError//发生内存溢出时,自动dump
-XX:+DisableExplicitGC//禁止代码中显示调用GC
-XX:+PrintGCDetails//打印GC详细日志
-XX:+PrintGCTimeStamps//输出GC的时间戳(以基准时间的形式),个人建议使用PrintGCDateStamps以日期形式输出
-XX:+PrintCommandLineFlags
-XX:+UseConcMarkSweepGC //使用cms gc收集算法
-XX:+UseParNewGC//并发串行收集器
-XX:ParallelCMSThreads=4//并发CMS过程运行时的线程数
-XX:+CMSClassUnloadingEnabled//垃圾回收会清理持久代,移除不再使用的classes
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=1//在上一次CMS并发GC执行过后,到底还要再执行多少次full GC才会做压缩
-XX:CMSInitiatingOccupancyFraction=72//是指设定CMS在对年老代使用占用率达到70%的时候开始GC(因为CMS会有浮动垃圾,所以一般都较早启动GC);
-XX:+UseCMSInitiatingOccupancyOnly//只是用设定的回收阈值(上面指定的70%),如果不指定,JVM仅在第一次使用设定值,后续则自动调整.
根据计算,各内存容量分配如下:
总堆内存为4g = 4014M
年轻代总大小=737M,(其中S1=73.7M,S2=73.7M,eden=590M)
年老代=737 * 4 = 2948M
元空间大小 = 4014M - 737M - 2948M = 329M,其中元空间是动态变化的,而年轻代和年老代是按比值配置的,因为也是小幅度动态变化的。
CMS GC要决定是否在full GC时做压缩,会依赖几个条件。其中,
第一种条件,UseCMSCompactAtFullCollection 与 CMSFullGCsBeforeCompaction 是搭配使用的;前者目前默认就是true了,也就是关键在后者上。
第二种条件是用户调用了System.gc(),而且DisableExplicitGC没有开启。
第三种条件是young gen报告接下来如果做增量收集会失败;简单来说也就是young gen预计old gen没有足够空间来容纳下次young GC晋升的对象。