主要垃圾回收算法与Hotspot VM垃圾回收器实现

垃圾回收算法

引用计数法

统计每个存活对象的引用次数,引用次数为0的对象视为待回收的垃圾对象。
引用计数法的弊端是无法回收循环引用的对象。如A引用B,B引用A,同时A和B都没有其他引用,此时A和B应该都是待回收的垃圾对象,但引用计数法无法识别。
因此,引用计数法已几乎不再被现代的编程语言使用。而是以另一种称为“可达性分析”的算法替代,下述的标记-清除、拷贝、标记-压缩算法都属于可达性分析算法。

可达性分析算法:
从GC Roots开始遍历内存池中的所有对象,任何能够从GC Roots直接或间接引用到的对象便被标记为“可达”,待遍历完成后,所有未被标记为“可达”的对象即为待回收的垃圾对象

GC Roots:
垃圾回收器用于进行可达性分析的根对象,GC Roots通常会有多个,以Java为例,一个运行中的JVM,其GC Roots可能包括:
Class - 由系统类加载器(system class loader)加载的对象
Thread - 所有活着的线程
Stack Local - Java方法的local变量或参数
JNI Local - JNI方法的local变量或参数
JNI Global - 全局JNI引用
Monitor Used - 用于同步的监控对象
Held by JVM - 用于JVM特殊目的由GC保留的对象,但实际上这个与JVM的实现是有关的。可能已知的一些类型是:系统类加载器、一些JVM知道的重要的异常类、一些用于处理异常的预分配对象以及一些自定义的类加载器等

标记-清除算法(Mark-Sweep)

也被称为Mark-Clean算法
标记阶段:从GC Roots开始进行可达性分析,将所有可达对象标记出来
清除阶段:将所有未标记可达的对象清理掉
标记-清除算法带来的问题是内存碎片,被清除掉的对象会在内存中留下很多的“洞”,这些“洞”的大小可能不足以容下新创建的对象,随着碎片的增多,内存池中实际可用的内存可能会变得越来越少

拷贝算法

  • 将内存划分为两个区域,一次只使用其中一个(暂称为from区)
  • 在进行可达性分析的同时,将可达对象复制到另一个空白的内存区域中(暂称为to区)
  • 可达性分析完成后,将to区与from区的身份互换,同时将原先的from区(现在的to区)中的对象清除

拷贝算法可以解决内存碎片的问题,因为向to区中复制的对象使用的都是连续的内存空间。同时拷贝算法的效率要比标记-清除算法高很多(尤其是在存活对象少、垃圾对象多的场景下),但代价是占用了冗余的内存空间。

标记-压缩算法(Mark-Sweep-Compact)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值