JVM垃圾回收(二)-垃圾收集算法

标记-清除算法

含义: 最基础的收集算法是“标记清除算法”,算法分为“标记”和清除两个阶段;首先标记出所有需要回收的对象,在标记完成后统一回收到所有被标记的对象。
主要问题:

  • 效率问题,标记和清除两个工程效率都不高
  • 空间问题,标记清楚后会产生大量不连续的内存空间,如图所示

复制算法

含义:将内存按容量划分为大小相等的两块,每次只使用其中的一块。当着一块的内存用完了,就讲还活着的对象复制到另外一块上面,然后在吧已使用过的内存空间一次性清理掉。这样使得每次都是对整个半区进行内存回收,内存分配是也不用考虑内存碎片等复制的情况。只要移动堆顶指针,按顺序分配内存既可。

  • 优点:实现简单,运行高效
  • 代价:讲内存缩小为原来的一半
    复制算法的执行过程如图所示

新生代中的复制算法

先引入两个概念,在JVM堆内存中,又分为新生代和老年代

  • 新生代:主要是用来存放新生的对象。一般占据堆的1/3空间。
  • 老年代:主要存放应用程序中生命周期长的内存对象。
    在Java虚拟机中一般都是采用这种收集算法来回收新生代。由于新生代中的对象98%是“朝生夕死”的,所以将内存分为较大的一块Eden空间和两块较小的Survive空间。
    每次使用Eden和其中一块Survive。当回收时,将Eden和Survive中还存活着的对象一次性复制到另外一块Survive空间上,最后清理掉Eden和刚在用过的Survive空间。
    在HotSpot虚拟机默认的比例是8:1(通过参数设置可以调整),也就是新生代可用内存空间为整个新生代容量的90%(80+10),由于无法保证每次回收都只有不多余10%的对象存活,当Survive空间不够用时,需要依赖其他内存进行分配(既老年代的内存)。
    注:新生代的复制将内存分为三块,而不是两块。和其本身的特性有关,暂时先不讨论

标记-整理算法

标记的过程与“标记清除”一样,但后续步骤不是直接对可回收的对象进行清理,而是将所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。如图所示

分代收集算法

根据对象存活的周期的不同将内存划分为几块,在根据不同的特点,采取最适当的收集算法

  • 新生代:存在大量的对象死亡,只有少数对象存活,采用复制算法
  • 老年代:因为对象存活率高,则采用标记整理算法进行回收
posted @ 2020-05-02 11:42  遗失的岁月  阅读(154)  评论(0编辑  收藏  举报