您的位置:首页 > 其它

HotSpot垃圾收集算法简介

2017-04-09 21:17 225 查看
经过对象存活算法的判定,可以得到一些等待被收集的垃圾对象。而这些对象要用什么方法收集呢?这里也是一个学问,有很多算法可以收集这些对象。下面简单介绍几种收集算法。

分代收集思想

当前大多数垃圾收集都采用“分代收集”的思想,就是把老年代和新生代分开用不同的算法进行收集。因为新生代每次垃圾收集的时候都会有大量死去的对象,而老年代一般情况都很少死去的对象。所以分代收集是很适合的一种方法。

标记-清除算法

标记清除算法分为两个阶段,标记和清除,它是最基础的收集算法,因为很多收集算法都是根据这个算法而改良而来的。

标记:就是事先标记所有需要回收的对象(也就是经过存活算法判定的)。

清除:清除掉所有标记的对象。

如下图所示:



标记清除算法有两个不足点:

1.效率问题,清除和标记两个过程效率都不高。

2.标记清除之后产生大量不连续的碎片内存,碎片太多而导致程序运行时分配大对象的时候得不到满足而又继续触发一次垃圾收集。

复制算法

复制算法把内存分为两个大小相等的部分,每次使用一块内存,另外一块空闲。当这一块内存用完了,把存活的对象复制到另外一块内存中有序的排列着。这样的好处是不用考虑内存碎片等问题,简单实现,运行高效。但是缺点也是显而易见,将内存缩小了一半,代价就有一点高了。如下图所示:



现在的商业虚拟机都采用这种复制算法来回收新生代。为什么呢?不是说内存会缩小一半吗?这是因为科学家们研究了,在新生代中,很多对象都是用完即可放弃的,这种对象占到了98%,所以并不需要1:1的空间,而是分成一块较大的Eden空间和两块较小的Survivor空间。每次都使用Eden和其中一块Survivor空间。当回收时,存活的对象复制到另外一块没有用到的Survivor空间中。

HotSpot默认的把Eden和Survivor大小的比例为8:1,也就是每次新生代中可用的内存是90%(80%+10%)。但是需要注意的是,当回收剩下存活的对象如果大于一个Survivor空间(大于10%),则需要依赖老年代的内存进行分配担保了。

标记-整理算法

复制算法对于内存空间存在很多存活率较高的对象时是非常的不适用的。所以老年代一般都不会使用复制算法。有人提出了一种类似标记-清除的算法,但是又有些地方不同。

首先是对可回收的对象进行标记,但是后续就不是清除了,而是对“存活的对象往一边移动”,从而清除掉最后一个存活对象后面的所有内存。

如下图所示:

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