新生代和老年代垃圾回收算法不同的原因
在新生代中。每次垃圾回收都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活的对象的复制成本就可以完成回收。而老年代中因为对象存活率高,没有额外空间对它进行担保,就需要用到"标记——清除"或者"标记整理"算法进行回收。
垃圾回收器之间的关系
图中上半部分是新生代垃圾回收器,下面是老年代垃圾回收器,连线就是可以搭配使用。没有最好的垃圾回收器,只有最适合的,存在即合理。
Serial(串行)/Serial Old
JVM刚诞生的时候就存在的最古老的垃圾回收器。特点是单线程,独占式,适合单CPU,一般在客户端模式下使用。
这种垃圾回收器只适合几十兆到一两百兆的堆空间进行垃圾回收。(可以把停顿时间控制在100ms左右)。如果超过这个内存大小,回收速度就会很慢。所以说这个垃圾回收器现在已经变成了鸡肋。(实际一般是当做CMS的替补使用)
运行时可通过参数设置,使新生代和老年代使用串行垃圾回收器。
Paraller(平行) Scaven/Paraller old
为了提高效率,从JDK1.3开始。JVM开始使用了多线程的垃圾回收机制。关注吞吐量的垃圾会收取,高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务。主要适合后台运算而没有太多交互的任务。(扩展:当CPU进行集中数据运算时,属于)
吞吐量:所谓的吞吐量就是CPU用于运行代码的时间与CPU消耗时间的比值,即吞吐流量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)。相当于用暴力手段处理STW的时间,并没有从根本去优化,但是依然取得了良好的效果。虚拟机总共运行了100分钟,其中垃圾回收占用了1分钟,那么吞吐量就是99%。
该垃圾回收器适合回收堆空间上百兆~几个G的内存。
运行时可通过参数设置,使新生代和老年代使用平行(多线程)垃圾回收器。
-XX:MaxGCPauseMillis
此参数可以主动设置STW的停顿时间。不过并不是把这个参数值设置小了就能使垃圾回收速度变快。垃圾收集停顿时间缩短是以牺牲吞吐量(垃圾回收变频繁)和新生代空间为代价换去的。当新生代空间变小时,垃圾回收的触发会变得越来越频繁,以换取更频繁的垃圾回收处理,从而变相使每次的STW的时间变少。但是每次启动也需要耗费时间。因此频繁的进行垃圾回收反而使吞吐量更低了。因此在多线程垃圾回收器中,这个值设置成默认的就可以了。此参数主要是为了G1垃圾回收器做服务的。
-XX:+UseAdaptiveSizePolicy
此参数默认开启。当参数**后,就不需要人工置顶分配新生代大小,Eden,Survivor区的比例。晋升老年代对象大小等细节参数了。虚拟机会根