You have a dream, you got to protect it. People can't do something by themselves; they wanna tell you you can not do it. You want something. Go get it!
本文将对垃圾回收器进行解读,主要知识来源于《深入了解Java虚拟机》。
垃圾收集器
Serial 收集器
Serial 收集器(串行收集器)该收集器是一个单线程收集器,回收线程启动时,其他线程必须停止工作,直到回收线程执行结束。
举例:当一个捕快在追捕犯人的时候要求,其他审判事件停止,对于被追捕的犯人来说是致命的,对于其他事件来说有点不太可能。
ParNew收集器
ParNew收集器其实就是Serial收集器的多线程版本,使用多条线程进行垃圾收集。
举例:当多个捕快在追捕多个犯人的时候要求,其他审判事件停止,对于被追捕的犯人来说是致命的,对于其他事件来说有点不太可能。
Parallel Scavenge收集器
Parallel Scavenge收集器(并行收集器)该收集器又被称之为“吞吐量优先”收集器,所谓的吞吐量就是CPU用于运行用户代码的时间与CPU总消耗的时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)其目标在于达到一个可控制的吞吐量。
Serial Old收集器
Serial Old收集器是Serial收集器的老年代版本,同样都是单线程收集器,使用的是标记整理算法。
Parallel Old收集器
Parallel Old收集器是Parallel Scavenge收集器老年代版本,使用多线程和标记整理算法。
CMS收集器
Concurrent Mark Sweep 收集器(并发收集器)是以一种获取最短回收停顿时间为目标的收集,它的运作过程相对于其他收集器来说更为复杂一点,整个过程分为4个步骤:
初始标记
并发标记
重新标记
并发清除
整个过程中耗时最长的并发标记和并发清除过程收集线程都可以与用户线程一起工作。
举例:当一个捕快在追捕犯人的时候先标记这个罪犯,其他审判事件执行,对于被追捕的犯人来说是重新标记,追捕犯人,送入监狱接着处理其他案件;不足在于追捕犯人时候看见其他犯罪事件,不能及时制止,只能先标记,下次再来追捕这个犯人。
缺点:
CMS收集器对CPU 资源非常敏感;
CMS收集器无法处理浮动垃圾
CMS收集器会产生大量空间碎片
G1收集器
G1收集器是一款面向服务端应用的垃圾收集器,回收整个过程分为4个步骤:
初始标记
并发标记
最终标记
筛选回收
与其他收集器相比,G1有以下特点:
并行与并发:充分利用多CPU、多核环境下的硬件优势来缩短停顿时间,通过并发方式让其他线程继续运行。
分代收集:采用不同方式去处理新创建的对象和已经存活一段时间、熬过多次GC的旧对象也可以获得很好的收集效果。
空间整合:从整体上来看是采用标记整理算法实现收集,从局部来看是采用复制算法来实现收集。
可预测的停顿:除了追求低停顿外,还建立了可预测的停顿时间模型 ,可以让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾回收时间不超过N毫秒。
之所以可以建立可预测的停顿时间模型,是因为他可以有计划地避免在Java堆上进行全区域的垃圾收集。 G1跟踪各个Region里面的垃圾堆积价值大小,在后台维护一个优先列表。这种使用Region划分内存空间以及有优先级回收区域的回收方式,保证了G1 收集器在有限时间内可以获最大的回收效率。
举例:普通衙门是一般捕快,效率比较低;要是六扇门捕快,效率高,对于不同的案件,犯人有自己的追捕方式,处理效率高,更可怕时可以预先知道凶案发生的时间、地点。
内存分配与回收策略
Minor GC ,Full GC
从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC;
对老年代GC称为Major GC;
而Full GC则是对整个堆GC。
对象优先在Eden分配,当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC(新生代垃圾回收);
大对象直接进入老年代、长期存活的对象进入老年代,虚拟机给每一个对象定义一个年龄计数器,如果新对象经历过一次Minor GC依旧存活,被survior容纳将收集到survior区,将对象年龄设置为1,每经历一次Minor GC,年龄加1,增加到一定年龄(默认15)将进入到老年代;
动态对象年龄判定,如果在survior区中相同年龄所有对象大小总和大于survior空间的一半,年龄大于等于该年龄对象可以直接进入到老年代。
Minor GC ,Full GC 触发条件
Minor GC 触发:Eden区没有足够空间进行分配时;
Full GC 触发:System.gc()方法的调用;老年代空间不足;通过Minor GC后进入老年代的平均大小大于老年代的可用内存。
本文要是有遗漏的地方,我将在评论区给出,同时对本文不当之处也会请在评论区指出。