您的位置:首页 > 编程语言 > Java开发

Java垃圾回收机制

2017-10-24 22:40 267 查看

Java垃圾回收机制

1)分代垃圾收集

HotSpot VM使用垃圾收集器,其垃圾收集算法是基于两个观察事实。

1.大部分分配对象的存活时间很短。

2.存活时间久的对象很少引用存活时间段的对象。

基于以上两个观察事实,HotSpot VM将堆划分为两个物理区(也称空间)——新生代和永久代,这就是分代。

新生代:大多数新创建对象被分配在新生代中,在java堆中,新生代空间较小且收集频繁。因为新生代收集(也称次要垃圾收集,记作Minor GC)关注较小且垃圾较多的垃圾对象(例如新生代)的空间,所以经过Minor GC后新生代中大部分对象存活时间短且垃圾收集效率高。HotSpot VM新生代分为以下3个独立区域。每经过一次Minor GC后新生代中的对象年龄增加一岁。只有足够老的对象才会进入老年代中。

Eden:大多数新对象分配在这里(大对象可能直接分配到老年代),经过Minor GC后依旧存活的对象被复制到To Survivor中。(Minor GC后Eden几乎为空)。

From Survivor:这里存放的对象至少经历过一次Minor GC,这里的对象因为不够“老”而不能存放在老年代中。经过MInor GC后若依旧存活且足够“老”的对像会提升到老年代中。不够老的对象会被复制到To Survivor中,最后与To Suvivor互换角色。

To Survivor:初始是这个空间为空,经过Minor GC后存放着来自Form Survivor以及Eden的对象,最后与From Survivor互换角色。

老年代:新生代中长期成活的对象最后会被提升到老年代中。通常,老年代空间回比新生代大、增长速度比新生代慢。相比Minor GC,老年代收集(也称主要垃圾收集或完全垃圾收集,记作Full GC)执行频率低,执行时间长。

2)Serial收集器

新生代中使用Serial收集器,采用之前的描述方式运行,而老年代中采用滑动压缩标记—清除算法(也称标记-压缩)。Serial收集器的Minor GC和Full GC都是以stop-the-wrold方式(即收集时停止运行应用程序。等垃圾收集结束后,应用才会继续运行。

标记-压缩收集器先是找出老年代中存活的对象,然后将它们滑向堆的头部,从而将所有空闲空间留在堆的尾部连续块中。

Serial收集器适合大多数对停顿时间要求不高和在客户端运行的应用。

3)parallel收集器(吞吐量为先)

为了减少垃圾收集器的开销而增加服务类的应用吞吐量,Parallel收集器采用与Serial一样的操作。然而Minor GC与Full GC是并行的,使用所有可用的处理器资源。

4)Mostly-Concurrent收集器(低延迟为先)

Mostly-Concurrent收集器也称(CMS(Concurrent Mark-Sweep)收集器)

CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器非常适合。它有以下几个过程。

初始标记 :在这个阶段,需要虚拟机停顿正在执行的任务,官方的叫法STW(Stop The Word)。这个过程从垃圾回收的”根对象”开始,只扫描到能够和”根对象”直接关联的对象,并作标记。所以这个过程虽然暂停了整个JVM,但是很快就完成了。

并发标记 :这个阶段紧随初始标记阶段,在初始标记的基础上继续向下追溯标记。并发标记阶段,应用程序的线程和并发标记的线程并发执行,所以用户不会感受到停顿。

并发预清理 :并发预清理阶段仍然是并发的。在这个阶段,虚拟机查找在执行并发标记阶段新进入老年代的对象(可能会有一些对象从新生代晋升到老年代, 或者有一些对象被分配到老年代)。通过重新扫描,减少下一个阶段”重新标记”的工作,因为下一个阶段会Stop The World。

重新标记 :这个阶段会暂停虚拟机,收集器线程扫描在CMS堆中剩余的对象。扫描从”跟对象”开始向下追溯,并处理对象关联。

并发清理 :清理垃圾对象,这个阶段收集器线程和应用程序线程并发执行。

并发重置 :这个阶段,重置CMS收集器的数据结构,等待下一次垃圾回收。

缺点:它需要较大的java堆且会使空间碎片化。

但是需要快速响应的应用会在CMS收集器中获益。

参考:《JAVA Performance》Charlie Hunt、Binu John著

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