什么是 GC Roots?一文带你看懂
创作时间:
作者:
@小白创作中心
什么是 GC Roots?一文带你看懂
引用
CSDN
1.
https://blog.csdn.net/m0_63653444/article/details/140323721
在Java虚拟机(JVM)中,GC Roots是垃圾回收机制中的核心概念。它决定了哪些对象应该被保留,哪些对象可以被回收。本文将通过类比和代码示例,帮助读者深入理解GC Roots的概念及其在垃圾回收中的作用。
什么是 GC Roots ?
JVM是如何判断哪些对象应该回收,哪些应该保留呢?答案就是GC Roots。
堆是一个巨大的对象集合,其中包含许多对象实例。这些对象在堆中有不同的引用层次。一些接口会被频繁调用,每秒生成大量对象。这些对象之间形成复杂的联系网络。尽管Java一直试图创造一种永无止境的内存感觉,但对象不能一直增加下去,因此需要进行垃圾回收。
JVM 是如何判断哪些对象应该回收,哪些应该保留呢?
古代有“诛九族”的想法。如果有人犯了大错,皇帝杀死一个人不足以平息他的怒火,那么会连坐其亲友。诛九族需要追溯到一个共同的祖先,然后向下延伸。在堆的垃圾回收中也有类似的思路。下面我们具体分析JVM如何执行垃圾回收。
JVM的垃圾收集动作是不受程序控制的,会在满足条件时自动启动。
在进行垃圾回收时,JVM能够追踪到对象的祖先引用。最终发现,如果这些祖先已经不再存在,它们将被清理掉。那些能够逃过垃圾回收的祖先非常特殊,它们被称为GC Roots。
GC Roots
通过从GC Roots开始向下追溯和搜索,形成一个称为“Reference Chain”(引用链)的链条。当一个对象无法与任何GC Root建立关联时,它将被无情地清除。
例如,Obj5、Obj6、Obj7由于无法与GC Roots关联,将在垃圾回收时被销毁。
垃圾回收就是围绕着GC Roots去做的。同时,它也是很多内存泄露的根源,因为其他引用根本没有这样的权利。
GC Roots是一组必须活跃的引用。用通俗的话来说,就是程序接下来通过直接引用或者间接引用,能够访问到的潜在被使用的对象
GC Roots包括:
- 虚拟机栈中引用的对象
- 当一个对象在虚拟机栈(栈帧中的本地变量表)中被引用时,它充当了GC Root的作用。例如:
public class Example {
public static void main(String[] args) {
Example obj = new Example(); // obj 是 GC Root
obj = null; // 断开 obj 对原对象的引用
}
}
- 在上面的示例中,obj是虚拟机栈中的本地变量,当obj被赋值为null时,原对象与GC Root断开连接,因此原对象会被回收。
- 方法区中类静态属性引用的对象
- 类静态属性引用的对象也是GC Roots。例如:
public class Example {
public static Example s; // 类静态属性引用的对象
public static void main(String[] args) {
Example obj = new Example();
obj.s = new Example(); // s 是 GC Root
obj = null; // 断开 obj 对原对象的引用
}
}
- 在上面的示例中,当栈帧中的本地变量obj=null时,由于obj原来指向的对象与GC Root(变量obj)断开了连接,所以obj原来指向的对象会被回收,而由于我们给s赋值了变量的引用,s在此时是类静态属性引用,充当了GC Root的作用,它指向的对象依然存活
- 方法区中常量引用的对象
- 常量引用的对象也不会因为其他引用断开而被回收。例如:
public class Example {
public static final Example CONSTANT = new Example(); // 常量引用的对象
public static void main(String[] args) {
Example obj = new Example();
obj = null; // 断开 obj 对原对象的引用,但 CONSTANT 不受影响
}
}
- 在上面的示例中,常量CONSTANT指向的对象不会因为obj的断开而被回收。
- 本地方法栈中JNI引用的对象
- JNI(Java Native Interface)是Java调用非Java代码的接口,本地方法栈中JNI引用的对象也是GC Roots。例如:
JNIEXPORT void JNICALL Java_com_pecuyu_jnirefdemo_MainActivity_newStringNative(JNIEnv *env, jobject instance,jstring jmsg) {
...
// 缓存String的class
jclass jc = (*env)->FindClass(env, STRING_PATH);
}
有两个注意点:
- 我们这里说的是活跃的引用,而不是对象,对象是不能作为GC Roots的。
- GC过程是找出所有活对象,并把其余空间认定为“无用”;而不是找出所有死掉的对象,并回收它们占用的空间。所以,哪怕JVM的堆非常的大,基于tracing的GC方式,回收速度也会非常快。
热门推荐
网易云相册照片权限管理指南
房产分割完全指南:从共同共有到婚后房产分配
核与辐射事故应急处理及防护指南
软件工作全解析:职业路径、技能要求与项目管理工具推荐
营造温馨氛围的实用技巧
每天坚持步行有8大好处,其中2个很多人都不知道
病毒性肝炎一站式全了解!传播途径、检测、预防、治疗......
如何理解和掌握平抛运动的基本概念
社会交换理论:揭秘社交媒体互动背后的深层动机
欧洲移民潮形成的原因?全面解读影响因素与社会变化
工商业燃气报警器安装全攻略:从选购到维护的实用指南
《自然·医学》:重新定义APOE4与阿尔茨海默病的关系
英国驾照理论考试指南:报名流程、题型解析与备考建议
国学文化讲堂 | 中华汉字故事:龙
胃痛和胃癌鉴别区别
焦虑症的根源是什么?揭秘心理健康之谜
玉米油的执行标准号是多少 玉米油的等级划分及选购攻略
病理与临床前沿技术研讨会:FISH伴随诊断在消化系统肿瘤中的应用
桐城法院与司法局联动调解 高效化解工伤纠纷 为劳动者权益保障按下“快捷键”
虚拟机如何更改开机画面
当冬晴遇上暖阳,九首诗词里的冬日温柔与希望
周一,正式确诊为INFP
瑞德西韦中国两项临床试验已停止,最新进展情况如何?
中国2025-2035:高端装备制造产业发展战略研究
古蜀文明神秘面纱进一步被揭开,这些三星堆文物“重见天日”
德国深度游:历史文化与现代魅力交织,畅享德意志之旅
辅警可以开罚单吗?
负面思维过重,怎么办?
青岛啤酒博物馆:百年啤酒文化的沉浸式体验
校园共享吹风机:便利背后的安全考量