常用的垃圾回收算法

1.标记清除算法

       标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段

       在标记阶段首先通过根节点(GC Roots),标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。

适用场合:

    • 适用于年老代(即旧生代)
    • 存活对象较多的情况下比较高效

    缺点:

      • 容易产生内存碎片,再来一个比较大的对象时(典型情况:该对象的大小大于空闲表中的每一块儿大小但是小于其中两块儿的和),会提前触发垃圾回收
      • 扫描了整个空间两次(第一次:标记存活对象;第二次:清除没有标记的对像)

      2.复制算法

            复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的

            从根集合节点进行扫描,标记出所有的存活对象,并将这些存活的对象复制到一块儿新的内存(图中下边的那一块儿内存)上去,之后将原来的那一块儿内存(图中上边的那一块儿内存)全部回收掉

            现在的商业虚拟机都采用这种收集算法来回收新生代

      适用场合:

        • 存活对象较少的情况下比较高效
        • 扫描了整个空间一次(标记存活对象并复制移动)
        • 适用于年轻代(即新生代):基本上98%的对象是"朝生夕死"的,存活下来的会很少

        缺点:

          • 需要一块儿空的内存空间
          • 需要复制移动对象

          3.标记整理算法

                标记-整理算法是一种老年代的回收算法,它在标记-清除算法的基础上做了一些优化

                这种情况在新生代经常发生,但是在老年代更常见的情况是大部分对象都是存活对象。如果依然使用复制算法,由于存活的对象较多,复制的成本也将很高

                首先也需要从根节点开始对所有可达对象做一次标记,但之后,它并不简单地清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。这种方法既避免了碎片的产生,又不需要两块相同的内存空间,因此,其性价比比较高

          4.分代收集算法

                分代收集算法就是目前虚拟机使用的回收算法,它解决了标记整理不适用于老年代的问题,将内存分为各个年代。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),在堆区之外还有一个代就是永久代(Permanet Generation)

                在不同年代使用不同的算法,从而使用最合适的算法,新生代存活率低,可以使用复制算法。而老年代对象存活率搞,没有额外空间对它进行分配担保,所以只能使用标记清除或者标记整理算法

          5.引用计数法

            • 每个对象都有一个引用计数器,当有新的引用指向该对象时,计数器加1;当某个引用失效时,计数器减1。
            • 当某对象的引用计数变为0时,则表示没有引用指向该对象,因此可以回收其占用的内存空间。
            • 优点是实现简单,实时性好;缺点是对循环引用无法处理

            6.思维导图(相关文章)

            相关文章:JVM高频面试知识总结,上万字的思维导图-CSDN博客

            ### JVM 常用垃圾回收算法及其工作原理 #### 标记-清除算法 (Mark-Sweep) 标记-清除算法是最基本的一种垃圾收集方法。该算法分为两个主要阶段: - **标记阶段**:遍历对象图并标记所有可访问的对象,确保这些对象不会被误删。 - **清除阶段**:扫描堆内存中的对象,释放那些未被标记(即不可达)的对象所占有的空间。 这种方法简单直观,但在实际应用中有两大缺陷:效率低以及容易产生大量碎片化内存[^5]。 #### 复制算法 (Copying) 为了克服标记-清除法产生的内存碎片问题,引入了复制算法。此算法将可用内存按容量划分为大小相等的两部分,每次只使用其中一部分,在进行垃圾回收时把存活对象复制到另一部分区域中去。这样不仅解决了内存碎片的问题,而且由于只需要移动指针即可完成清理操作,因此速度更快。不过这种做法浪费了一半的空间资源[^2]。 ```java // 示例代码展示如何模拟简单的复制过程 public class CopyingGC { private static final int MAX_HEAP_SIZE = 8 * 1024; // 单位KB public void copyObjects() { Object[] fromSpace = new Object[MAX_HEAP_SIZE / 2]; Object[] toSpace = new Object[MAX_HEAP_SIZE / 2]; // 执行复制逻辑... } } ``` #### 标记-整理算法 (Mark-Compact) 标记-整理算法综合了前两种方案的优点。同样先经过一轮完整的标记过程来识别哪些对象仍然活跃;之后不是直接删除无用对象腾出位置给新创建的数据结构,而是让所有的存活对象向一端聚集靠拢,从而消除因多次分配和释放造成的零散空闲区。这种方式既避免了内存碎片又提高了存储利用率[^4]。 #### 分代收集算法 (Generational Collection) 考虑到大多数情况下新生代中的对象生命周期较短而老年代里的则相对持久的特点,分代收集算法应运而生。整个堆被分割成几个不同年龄层次的部分——年轻代(Young Generation) 和年老代(Tenured/Old Generation),针对各自特性采取最适宜它们自身的回收方式。比如对于年轻人来说采用快速但可能不彻底的方式处理,而对于老年人则更倾向于稳健可靠的策略[^3]。
            评论
            添加红包

            请填写红包祝福语或标题

            红包个数最小为10个

            红包金额最低5元

            当前余额3.43前往充值 >
            需支付:10.00
            成就一亿技术人!
            领取后你会自动成为博主和红包主的粉丝 规则
            hope_wisdom
            发出的红包
            实付
            使用余额支付
            点击重新获取
            扫码支付
            钱包余额 0

            抵扣说明:

            1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
            2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

            余额充值