jvm中的垃圾收集算法

来源:互联网 发布:linux开机动画 编辑:程序博客网 时间:2024/06/02 01:00

Java虚拟机会回收已经失效的对象,判断对象是否失效使用的是可达性分析算法,那么JVM是对失效的对象的回收过程是怎样做的呢,它的算法实现是怎样的呢?
【本人现能力不足,只能理解这几种回收算法的思想,无法写出它们的代码实现,如果可以,本人将在后续完成它的代码实现】


标记——清除算法

标记清除算法是最基础的收集算法,它的执行过程分为俩步:标记、清除。首先是要标记出所有可以被回收的对象,在标记完成后统一回收所有被标记的对象。之所以说它是最基础的垃圾回收算法,是因为其他的算法都是基于这种思路,但是对这个算法的不足之处进行了改进。那它的不足之处主要有俩点:

  • 效率问题:标记和清除这俩个过程的效率都不高。为什么效率不高呢?原因是jvm通过可达性分析算法来确定对象它是否应该被标记。在执行标记的时候会使用到深度优先算法与广度优先算法,还会使用递归算法,所以效率很低。清除阶段需要遍历整个堆,所以效率也不高。【如果有兴趣详细了解算法实现,请浏览图灵社区】
  • 空间问题:标记清除后会产生大量的不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大的对象时,无法找到足够的连续的内存空间从而不得不触发另一次的垃圾回收。

复制算法

为了解决效率问题,复制算法出现。它将可用内存按容量划分为大小相同的俩块,每次只使用其中的一块。 当这一块的内存用完了,就将还存活着的对象复制到另外一块内存上去,然后把已使用过的内存空间一次性的清理掉,这样使得每次都是对整个半区进行回收,内存分配时也就不用分配内存碎片等复杂情况,只要移动栈顶指针,按顺序分配内存即可,实现简单,运行高效。只是这种算法将会牺牲掉一半的内存,资源浪费严重。


标记——整理算法

复制收集算法在对象存活率较高的时候要进行较多的复制,效率就会降低.更关键的是如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象100%存活的极端情况,所以在老年代一般不使用这种算法。根据老年代的特点,有人提出了标记整理算法,标记过程与标记清除算法一样,但后续步骤不是直接对对象进行回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。


分代收集算法

就是根据各个年代的特点采用最适当的收集算法。

0 0