常见的垃圾回收算法

11 篇文章 0 订阅

判断对象是否可以被回收的算法

  • 引用计数器法(Reference Count):

    为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题。
    循环引用问题:A->B;B->C;C->A;并且A、B、C都是垃圾

  • 可达性分析算法(Root Searching):

    从 根节点(GC Roots) 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。
    可以作为root根的有:栈里边的局部变量,方法区里的静态引用、常量等。

进行垃圾回收的算法

  • 标记-清除算法:

    标记无用对象,然后进行清除回收,这个算法相对比较简单,在存活对象比较多的情况下效率比较高
    优点:实现简单,效率比较高,不需要对象进行移动。
    缺点:标记、清除过程效率低,产生大量不连续的内存碎片,提高了垃圾回收的频率。

  • 标记-复制算法:

    按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。
    优点:实现简单、运行高效,没有内存碎片。
    缺点:可用的内存大小缩小为原来的一半,对象存活率高时会频繁进行复制,需要调整对象引用

  • 标记-整理算法:

    标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
    优点:不会产生内存碎片,可用空间也不会减半
    缺点:仍需要进行局部对象移动,一定程度上降低了效率。

分代算法

JVM根据对象存活周期的不同将内存划分为几块,一般包括年轻代、老年代和永久代(元空间),新生代基本采用复制算法,老年代采用标记整理算法。

在这里插入图片描述

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。
新生代使用的是标记-复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下:

把 Eden + From Survivor 存活的对象放入 To Survivor 区;
清空 Eden 和 From Survivor分区;
From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。

每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代。
老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记-整理算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值