java -XX:+PrintFlagsFinal,可打印所有jvm的默认配置参数。
JDK8中,XX:MaxMetaspaceSize是没有上限的,最大容量与机器的内存有关;但是XX:MetaspaceSize有一个默认值的:21M。
从JDK8开始,永久代(PermGen)的概念被废弃了,取而代之的是一个称为Metaspace的存储空间。Metaspace使用的是本地内存,而不是堆内存,在默认情况下Metaspace的大小只与本地内存大小有关。可以通过以下几个参数对Metaspace进行控制:
-XX:MetaspaceSize=N(字节)
这个参数是初始化的Metaspace大小,该值越大触发Metaspace GC的时机就越晚。随着GC的到来,虚拟机会根据实际情况调控Metaspace的大小,可能增加也可能降低。在10M到21M间浮动。
-XX:MaxMetaspaceSize=N(字节)
这个参数用于限制Metaspace增长的上限,防止Metaspace无限的使用本地内存,影响到其它程序。默认值4g左右。
-XX:MinMetaspaceFreeRatio=N(%)
当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比。如果空闲比小于这个参数,那么虚拟机将增加Metaspace的大小。该参数的默认值为40,也就是40%。设置该参数可以控制Metaspace的增长速度,太小的值会导致Metaspace增长缓慢,Metaspace的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致Metaspace增长过快,浪费内存。
-XX:MaxMetasaceFreeRatio=N(%)
当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比。如果空闲比大于这个参数,那么会释放Metaspace的部分空间。默认值为70,也就是70%。
-XX:MaxMetaspaceExpansion=N(字节)
Metaspace增长时的最大幅度。默认值为5452592B(大约为5MB)。
-XX:MinMetaspaceExpansion=N(字节)
Metaspace增长时的最小幅度,默认值为340784B(大约330KB为)。
常规
参数 | 说明 |
-Xms | 初始堆大小。 默认空余堆内存小于40%时(MinHeapFreeRatio参数),JVM会增大堆直到-Xmx的最大限制。 同-XX:InitialHeapSize。 默认:物理内存的1/64(<1GB)。 |
-Xmx | 最大堆大小 默认空余堆内存大于70%时(MaxHeapFreeRatio参数),JVM会减少堆直到-Xms的最小限制。 同-XX:MaxHeapSize。 默认:物理内存的1/4(<1GB) |
-Xmn | 年轻代大小(eden + 2*survivor)。 同-XX:NewSize。 |
-XX:NewSize | 年轻代大小(for 1.3/1.4) |
-XX:MaxNewSize | 年轻代最大值(for 1.3/1.4) |
-XX:PermSize | 持久代(perm gen)初始值。物理内存的1/64。 jdk8取消,用metaspace替代。 |
-XX:MaxPermSize | 持久代最大值。物理内存的1/4。 jdk8取消,用metaspace替代。 |
-Xss | 每个线程的栈大小。默认:1M。 在相同物理内存下,减小这个值能产生更多线程。建议在3000~5000左右。 同-XX:ThreadStackSize。 |
-XX:ThreadStackSize | 线程栈大小,默认320。 |
-XX:NewRatio | 年轻代与年老代在堆中所占比值。默认为1:2。 Xms=Xmx且设置了Xmn时,该参数失效。 |
-XX:SurvivorRatio | Eden与Survivor的比值。默认:8。 两个Survivor与一个Eden的比值为1:1:8。 |
-XX:LargePageSizeInBytes | 内存页的大小,不可设置过大,会影响Perm的大小。默认128m |
-XX:+UseFastAccessorMethods | 原始类型的快速优化 |
-XX:+DisableExplicitGC | 关闭System.gc() |
-XX:MaxTenuringThreshold | 控制对象经历多少次Minor GC才晋升到老年代。 设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。如果设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代被回收的概率。 该参数只有在串行GC时才有效。 |
-XX:+AggressiveOpts | 加快编译 |
-XX:+UseBiasedLocking | 锁机制的性能改善 |
-Xnoclassgc | 禁用垃圾回收 |
-XX:SoftRefLRUPolicyMSPerMB | 每MB堆的空闲空间中软引用的存活时间。默认1秒。 软可达对象在它们最后一次被引用后的存活时间。 |
-XX:PretenureSizeThreshold | 对象超过多大直接在老年代分配。默认:0 当年轻代采用Parallel Scavenge GC时无效。 另一种直接在老年代分配的是大数组对象,且数组中无外部引用对象。 |
-XX:TLABWasteTargetPercent | TLAB占eden区的百分比。默认:1%。 |
-XX:+CollectGen0First | FullGC时是否先YGC。默认:false。 |
并行收集参数
-XX:+UseParallelGC | 选择垃圾收集器为并行收集器。 仅对年轻代有效。 |
-XX:+UseParNewGC | 设置年轻代为并行收集,JVM自动配置,无需设置。 |
-XX:ParallelGCThreads | 并行收集器的线程数。 最好与处理器数目相等,同样适用于CMS。 |
-XX:+UseParallelOldGC | 年老代并行收集。 |
-XX:MaxGCPauseMillis | 每次年轻代回收的最长时间(最大暂停时间)。 如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。 |
-XX:+UseAdaptiveSizePolicy | 自动选择年轻代区大小和相应的Survivor区比例。 设置后,并行收集器会自动选择年轻代和Survivor的比例,以达到系统规定的最低响应时间或收集频率等,建议使用并行收集器时打开。 |
-XX:GCTimeRatio | 设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)。 |
-XX:+ScavengeBeforeFullGC | FGC前调用YGC。默认:true。 |
CMS参数
-XX:+UseConcMarkSweepGC | 使用CMS收集策略。 |
-XX:CMSFullGCsBeforeCompaction | CMS执行多少次后进行内存压缩。 默认0。 |
-XX:+CMSParallelRemarkEnabled | 降低标记停顿。默认true。 |
-XX+UseCMSCompactAtFullCollection | 在FGC时对年老代压缩。默认true。 |
-XX:CMSInitiatingOccupancyFraction | 设定CMS在对内存占用率达到N%的时开始GC。默认-1。 为了保证不出现promotion failed错误,需要满足公式: CMSInitiatingOccupancyFraction值与Xmn的关系。 |
-XX:+UseCMSInitiatingOccupancyOnly | 设定回收阈值。由CMSInitiatingOccupancyFraction指定,如果不指定,JVM仅在第一次使用设定值,后续则自动调整 |
-XX:+CMSIncrementalMode | 设置为增量模式。默认:false。 |
-XX:+CMSClassUnloadingEnabled | CMS收集器会对永久代进行垃圾回收。 默认:true |
辅助
-XX:+PrintGC | 输出形式: [GC 118250K->113543K(130112K), 0.0094143 secs] [Full GC 121376K->10414K(130112K), 0.0650971 secs] |
-XX:+PrintGCDetails | 输出形式: [GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs] |
-XX:+PrintGCTimeStamps | 打印自JVM启动时的时间戳 |
-XX:+PrintGC:PrintGCTimeStamps | 输出形式: 11.851: [GC 98328K->93620K(130112K), 0.0082960 secs] |
-XX:+PrintGCApplicationStoppedTime | 打印垃圾回收期间程序暂停的时间。 输出形式: Total time for which application threads were stopped: 0.0468229 seconds |
-XX:+PrintGCApplicationConcurrentTime | 打印每次垃圾回收前,程序未中断的执行时间 输出形式: Application time: 0.5291524 seconds |
-XX:+PrintHeapAtGC | 打印GC前后的详细堆栈信息 |
-Xloggc:filename | 把日志信息记录到文件
|
-XX:+PrintClassHistogram | 在打印类的结构图前作垃圾收集。 |
-XX:+PrintTLAB | 查看TLAB空间的使用情况 |
-XX:+PrintTenuringDistribution | 查看每次Minor GC后新的存活周期的阈值。 |
-
promotion failed:
垃圾回收时promotion failed是个很头痛的问题,一般可能是两种原因产生,第一个原因是救助空间不够,救助空间里的对象还不应该被移动到年老代,但年轻代又有很多对象需要放入救助空间;第二个原因是年老代没有足够的空间接纳来自年轻代的对象;这两种情况都会转向Full GC,网站停顿时间较长。
解决方案一:
第一个原因的最终解决办法是去掉救助空间,设置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可,第二个原因我的解决办法是设置CMSInitiatingOccupancyFraction为某个值(假设70),这样年老代空间到70%时就开始执行CMS,年老代有足够的空间接纳来自年轻代的对象。
解决方案一的改进方案:
又有改进了,上面方法不太好,因为没有用到救助空间,所以年老代容易满,CMS执行会比较频繁。我改善了一下,还是用救助空间,但是把救助空间加大,这样也不会有promotion failed。具体操作上,32位Linux和64位Linux好像不一样,64位系统似乎只要配置MaxTenuringThreshold参数,CMS还是有暂停。为了解决暂停问题和promotion failed问题,最后我设置-XX:SurvivorRatio=1 ,并把MaxTenuringThreshold去掉,这样即没有暂停又不会有promotoin failed,而且更重要的是,年老代和永久代上升非常慢(因为好多对象到不了年老代就被回收了),所以CMS执行频率非常低,好几个小时才执行一次,这样,服务器都不用重启了。
-Xmx4000M -Xms4000M -Xmn600M -XX:PermSize=500M -XX:MaxPermSize=500M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log
-
CMSInitiatingOccupancyFraction值与Xmn的关系公式
上面介绍了promontion faild产生的原因是EDEN空间不足的情况下将EDEN与From survivor中的存活对象存入To survivor区时,To survivor区的空间不足,再次晋升到old gen区,而old gen区内存也不够的情况下产生了promontion faild从而导致full gc.那可以推断出:eden+from survivor < old gen区剩余内存时,不会出现promontion faild的情况,即:
(Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)>=(Xmn-Xmn/(SurvivorRatior+2))
进而推断出:
CMSInitiatingOccupancyFraction <=((Xmx-Xmn)-(Xmn-Xmn/(SurvivorRatior+2)))/(Xmx-Xmn)*100
例如:
当xmx=128 xmn=36 SurvivorRatior=1时,
CMSInitiatingOccupancyFraction<=((128.0-36)-(36-36/(1+2)))/(128-36)*100 =73.913
当xmx=128 xmn=24 SurvivorRatior=1时,
CMSInitiatingOccupancyFraction<=((128.0-24)-(24-24/(1+2)))/(128-24)*100=84.615…
当xmx=3000 xmn=600 SurvivorRatior=1时,
CMSInitiatingOccupancyFraction<=((3000.0-600)-(600-600/(1+2)))/(3000-600)*100=83.33
CMSInitiatingOccupancyFraction低于70%,需要调整xmn或SurvivorRatior值。