关于gc root的思考

本文详细解析了GCRoot的概念及其在不同垃圾回收场景中的应用,包括fullgc、younggc和oldgc,探讨了跨代引用的重要性,并对特殊情况下跨代引用的必要性进行了深入思考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一.概念

二.gc root 的具体内容

    1.full gc (收集整个堆)

    2.young gc(只收集年轻代)

    3.old gc(只收集老年代,特指cms)

三.关于跨代引用的思考


一.概念

gc root 指的根引用的集合在分代模型中,对于收集不同区域,gc root的集合有些许不同

 

二.gc root 的具体内容

    1.full gc (收集整个堆)

•虚拟机栈中的引用

•JVM的一些静态数据结构里指向GC堆里的对象的引用,例如Universe

•JNI handles,包括global handles和local handles

•类的静态变量的引用 (实例在堆区,引用在instanceKlass?)

•类的运行时常量池里的引用类型常量

•String常量池(StringTable)里的引用 (实例在堆区,引用在方法区?)

    2.young gc(只收集年轻代)

在full gc的gc root基础上多了old区,原因是可能存在old区对象对young区对象的引用。由于老年代很大,所以并不会扫描整个老年代,而是采用remember set的形式将老年代分成很多card,只扫描dirty card。(图片来自网络)

 

    3.old gc(只收集老年代,特指cms)

同理,在full gc的gc root基础上多了young区。会扫描整体young区,可能导致cms最终标记时间变长,因此cms可设置XX:+CMSScavengeBeforeRemark来控制在最终标记前执行一次young gc(并不会绝对执行,jvm会做一定判断)。

三.关于跨代引用的思考

如果young gc 时不将old区作为根,会出现old区对象存活而它指向的young区对象被回收的情况,这种情况下old区对象当前应该也是不可达的,这样的话应该也没有什么问题,那么为什么一定要做跨代引用的判断呢?这个问题我想了很久,想到了一种特殊情况:虽然old区对象当前不可达,但是有可能被回收时执行finalize方法而复活了自己,所以一定要做跨代引用的判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值