GCRoots是什么?哪些对象可以作为GCRoot?看完秒懂!

更新时间:2023-07-12 23:09:23 阅读: 评论:0

属兔女和什么属相最配GCRoots是什么?哪些对象可以作为GCRoot?看完秒懂!什么是是可达性分析算法?
现代虚拟机基本都是采⽤可达性分析算法来判断对象是否存活,可达性算法的原理是以⼀系列叫做  GC Root  的对象为起点出发,引出它们指向的下⼀个节点,再以下个节点为起点,引出此节点指向的下⼀个结点。这样通过 GC Root 串成的⼀条线就叫引⽤链),直到所有的结点都遍历完毕,如果相关对象不在任意⼀个以 GC Root 为起点的引⽤链中,则这些对象会被判断为垃圾对象,会被 GC 回收。
如图⽰,如果⽤可达性算法即可解决上述循环引⽤的问题,因为从GC Root 出发没有到达 a,b,所以 a,b 可回收。
a, b 对象可回收,就⼀定会被回收吗?
并不是,对象的 finalize ⽅法给了对象⼀次垂死挣扎的机会,当对象不可达(可回收)时,当发⽣GC时,会先判断对象是否执⾏了finalize ⽅法,如果未执⾏,则会先执⾏ finalize ⽅法,我们可以在此⽅法⾥将当前对象与 GC Roots 关联,这样执⾏ finalize ⽅法之后,GC 会再次判断对象是否可达,如果不可达,则会被回收,如果可达,则不回收!
注意: finalize ⽅法只会被执⾏⼀次,如果第⼀次执⾏ finalize ⽅法此对象变成了可达确实不会回收,但如果对象再次被 GC,则会忽略finalize ⽅法,对象会被回收!这⼀点切记!
职业技能鉴定证书GC Roots 到底是什么东西呢,哪些对象可以作为 GC Root 呢?
虚拟机栈(栈帧中的本地变量表)中引⽤的对象
本地⽅法栈中 JNI(即⼀般说的 Native ⽅法)引⽤的对象
⽅法区中类静态属性引⽤的对象
⽅法区中常量引⽤的对象
便于记忆,称他为两栈两⽅法!下⾯我们⼀⼀介绍⼀下:
1、虚拟机栈中引⽤的对象
如下代码所⽰,a 是栈帧中的本地变量,当 a = null 时,由于此时 a 充当了 GC Root 的作⽤,a 与原来指向的实例 new Test() 断开了连接,所以对象会被回收。
publicclass Test {
public static  void main(String[] args) {
Test a = new Test();
a = null;
}
}
2、⽅法区中类静态属性引⽤的对象
如下代码所⽰,当栈帧中的本地变量 a = null 时,由于 a 原来指向的对象与 GC Root (变量 a) 断开了连接,所以 a 原来指向的对象会被回收,⽽由于我们给 s 赋值了变量的引⽤,s 在此时是类静态属性
论文页码引⽤,充当了 GC Root 的作⽤,它指向的对象依然存活!
public class Test {
public static Test s;
public static  void main(String[] args) {
Test a = new Test();
a.s = new Test();
a = null;
}
土犀}
3、⽅法区中常量引⽤的对象
计算机的组成如下代码所⽰,常量 s 指向的对象并不会因为 a 指向的对象被回收⽽回收五险一金基数
public class Test {
public static final Test s = new Test();
public static void main(String[] args) {
Test a = new Test();
a = null;
}
梦幻签到答题器
}
4、本地⽅法栈中 JNI 引⽤的对象
这是简单给不清楚本地⽅法为何物的童鞋简单解释⼀下:所谓本地⽅法就是⼀个 java 调⽤⾮ java 代码的接⼝,该⽅法并⾮ Java 实现的,可能由 C 或 Python等其他语⾔实现的, Java 通过 JNI 来调⽤本地⽅法, ⽽本地⽅法是以库⽂件的形式存放的(在 WINDOWS 平台上是 DLL ⽂件形式,在 UNIX 机器上是 SO ⽂件形式)。通过调⽤本地的库⽂件的内部⽅法,使 JAVA 可以实现和本地机器的紧密联系,调⽤系统级的各接⼝⽅法,还是不明⽩?见⽂末参考,对本地⽅法定义与使⽤有详细介绍。
当调⽤ Java ⽅法时,虚拟机会创建⼀个栈桢并压⼊ Java 栈,⽽当它调⽤的是本地⽅法时,虚拟机会保持 Java 栈不变,不会在 Java 栈祯中压⼊新的祯,虚拟机只是简单地动态连接并直接调⽤指定的本地⽅法。
JNIEXPORT void JNICALL Java_com_pecuyu_jnirefdemo_MainActivity_newStringNative(JNIEnv *env, jobject instance,jstring jmsg) {
...
// 缓存String的class
宾得jclass jc = (*env)->FindClass(env, STRING_PATH);
}
如上代码所⽰,当 java 调⽤以上本地⽅法时,jc 会被本地⽅法栈压⼊栈中, jc 就是我们说的本地⽅法栈中 JNI 的对象引⽤,因此只会在此本地⽅法执⾏完成后才会被释放。

本文发布于:2023-07-12 23:09:23,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1079042.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:对象   指向   回收
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图