您的位置:首页 > 职场人生

面试知识点5:JVM垃圾回收算法

2017-04-07 12:55 260 查看
1. 分代:年轻代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)。

    其中,年轻代有Eden/S0/S1。

2.回收分类:

Minor GC(新生代回收)的触发条件比较简单,Eden空间不足就开始进行Minor GC回收新生代。

而Full GC(老年代回收,一般伴随一次MinorGC)则有几种触发条件:

(1)老年代空间不足

(2)PermSpace空间不足

(3)统计得到的MinorGC晋升到老年代的平均大小大于老年代的剩余空间

 

这里注意一点:PermSpace并不等同于方法区,只不过是HotspotJVM用PermSpace来实现方法区而已,有些虚拟机没有PermSpace而用其他机制来实现方法区。

3. 垃圾回收器:

    
串行回收器(Serial Collector)单线程执行回收操作,回收期间暂停所有应用线程的执行,client模式下的默认回收器。把Eden区的存活对象移到To区,To区装不下直接移到年老代,把From区的移到To区,To区装不下直接移到年老代,From区里面年龄很大的升级到年老代。 回收结束之后,Eden和From区都为空,此时把From和To的功能互换,From变To,To变From,每一轮回收之前To都是空的。设计的选型为复制。年老代的回收分为三个步骤,标记(Mark)、清除(Sweep)、合并(Compact)。标记阶段把所有存活的对象标记出来,清除阶段释放所有死亡的对象,合并阶段把所有活着的对象合并到年老代的前部分,把空闲的片段都留到后面。设计的选型为合并,减少内存的碎片。
并行回收器(Parallel Collector)使用多个线程同时进行垃圾回收,多核环境里面可以充分的利用CPU资源,减少回收时间,增加JVM生产率,Server模式下的默认回收器。与串行回收器相同,回收期间暂停所有应用线程的执行。使用多个线程回收垃圾,每一个线程的算法与串行回收器相同。年老代依然是单线程的,与串行回收器相同。

并行合并收集器(Parallel Compacting Collection)

年轻代和年老代的回收都是用多线程处理。与并行回收器相比,年老代的回收时间更短,从而减少了暂停时间间隔(Pause time)。与并行回收器(ParallelCollector)相同年老代分为三个步骤,标记、统计、合并。这里用到分的思想,把年老代划分为很多个固定大小的区(region)。标记阶段,把所有存活的对象划分为N组(应该与回收线程数相同),每一个线程独立的负责自己那一组,标记存活对象的位置以及所在区(Region)的存活率信息,标记为并行的。统计阶段,统计每一个区(Region)的存活率,原则上靠前面的存活率较高,从前到后,找到值得合并的开始位置(绝大多数对象都存活的区不值得合并),统计阶段是串行的(单线程)。合并阶段,依据统计阶段的信息,多线程并行的把存活的对象从一个区(Region)复制到另外一个区(Region)。

并发标记清除回收器(Concurrent Mark-Sweep Collector)

又名低延时收集器(Low-latencyCollector),通过各种手段使得应用程序被挂起的时间最短。基本与应用程序并发地执行回收操作,没有合并和复制操作。与并行回收器(ParallelCollector)相同分为四个步骤,初始标记(Initial Mark)、并发标记(ConcurrentMark)、再次标记(Remark)、以及并发清理(Concurrent Sweep)。特别注意,没有合并操作,所以会有碎片。
初始化阶段: 暂停应用线程,找出所有存活的对象,耗时比较短,回收器使用单线程。

并发标记阶段: 回收器标记操作与应用并发运行,回收器使用单线程标记存活对象。

再次标记:并发标记阶段由于应用程序也在运行,这个过程中可能新增或者修改对象。所以再次暂停应用线程,找出所有修改的对象,使用多线程标记。

并发清理:回收器清理操作与应用并发运行,回收器使用单线程清理死亡对象。

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JVM GC