CMS垃圾回收器
初始标记 并发标记 重新标记 并发清理
默认回收线程数:(cpu核数+3)/ 4
如果在回收期间发生了Concurrent Mode Failure问题(一边回收,一边把对象放入老年代,内存都不够了)。此时就会自动用Serial Old垃圾回收器替代CMS,就是直接强行把系统程序Stop the World,重新进行长时间的GC Roots追踪,标记出来全部垃圾对象,不允许新的对象产生。可能需要设置此参数。
G1垃圾回收器
初始标记(STW),并发标记,最终标记(STW),混合回收(STW)
一个可以由用户指定STW的新一代垃圾回收器,其原则是在最短的时间内回收更多的垃圾(垃圾的回收价值)。G1将内存分为多个Region。Region随着时间的推移可在逻辑上分为新生代和老年代。
JVM启动时会检查是否使用的是G1,如果是,则自动计算Region的个数和数量,JVM最大可以有2048个Region,每个Region又必须是2的倍数,以4G堆内存为例,可以拥有2048个空间为最有4*1024 / 2048 = 2M的Region。可通过参数-XX:G1HeapRegionSize指定Region的个数。
新生代默认5%的Region个数,可通过-XX:G1NewSizePercent来指定初始占比,其实这个是动态的,维持默认值就行。新生代最大占比可使用-XX:G1MaxNewSizePercent来指定,默认为60%。
G1还是存在Eden和Survivor的,只不过是用Region来区分了。比如说8:1:1,则假如新生代有1000个Region,则Eden就有800个,Survivor均为100个。新生代回收还是采用复制算法。
因为G1还是有Eden和Survivor概念的,所以垃圾回收还是类似的。达到新生代最大的占比时,依然会将Eden和其中一块Survivor转移到另一块Survivor中。但是,G1可由用户指定STW的时间(可以用参数:-XX:MaxGCPauseMills,默认200毫秒),G1会保证在这段时间处理掉更多的垃圾。
对于G1来说,对象进入老年代跟传统的差不多,分为以下几种情况:
1.达到了年龄设置值,-XX:MaxTenuringThreshold
2.满足动态年龄:假如某次新生代回收之后,对象总大小大于Survivor的50%,此时就会判断年龄1~n岁的对象总大小是否超过Survivor的50%。如果超过,则n+1岁的对象进入老年代。
3.存活对象Survivor放不下
对于G1来说,当一个对象的大小超过Region的50%时,该对象被认为是大对象,大对象可以跨Region存储。新生代或老年代回收时,会顺带回收大对象。
G1回收的步骤跟CMS类似,分为:初始标记(STW),并发标记,最终标记(STW),混合回收(STW)。在混合回收阶段,会计算每个Region的对象数量,存活对象的占比还有执行垃圾回收的预期性能和效率,接着会STW选择部分Region进行回收。来达到STW必须在指定的时间内。
G1回收时,无论是年轻代还是老年代都是复制算法。一旦复制过程中产生了没有Region可承载存活对象,就会触发一次失败,此时会立刻停止系统程序,采用单线程标记、清理和压缩整理,空闲出来Region,这个过程很慢。