在 Java中什么样的对象才能作为gc root?

所谓“GC roots”,或者说tracing GC的“根集合”,就是一组必须活跃的引用。例如说,这些引用可能包括:

(1)所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用;换句话说,当前所有正在被调用的方法的引用类型的参数/局部变量/临时值。所有Java线程当前栈帧的引用和虚拟机内部线程(Threads::possibly_parallel_oops_do)
(2)VM的一些静态数据结构里指向GC堆里的对象的引用,例如说HotSpot VM里的Universe里有很多这样的引用。Java对象并不是只有用户才能new,虚拟机内部也new了一些
(3)JNI handles,包括global handles和local handles(看情况)
(4)所有当前被加载的Java类(看情况)(ClassLoaderDataGraph::roots_cld_do)
(5)Java类的引用类型静态变量(看情况)
(6)Java类的运行时常量池里的引用类型常量(String或Class类型)(
(7)看情况)String常量池(StringTable)里的引用

作者:RednaxelaFX
链接:https://www.zhihu.com/question/53613423/answer/135743258
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


什么是gc root,JVM在进⾏垃圾回收时,需要找到“垃圾”对象,也就是没有被引⽤的对象,但是直接 找“垃圾”对象是⽐较耗时的,所以反过来,先找“⾮垃圾”对象,也就是正常对象,那么就需要从某些“根”开始去找,根据这些“根”的引⽤路径找到正常对象,⽽这些“根”有⼀个特征,就是它只会引⽤其他对象,⽽不会被其他对象引⽤,例如:栈中的本地变量、⽅法区中的静态变量、本地⽅法栈中的变量、正在运⾏的线程等可以作为gc root。

作者:麒麟改bug
链接:https://www.zhihu.com/question/50381439/answer/1968724484
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


当前正在使用的:1、虚拟机栈中引用的对象 2、4、本地方法栈中 JNI 引用的对象

全局和JVM生命周期一直的:2、方法区中类静态属性引用的对象、3、方法区中常量引用的对象 4、本地方法栈中 JNI 引用的对象

当调用 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);
}

https://blog.csdn.net/weixin_38007185/article/details/108093716
如上代码所示,当 java 调用以上本地方法时,jc 会被本地方法栈压入栈中, jc 就是我们说的本地方法栈中 JNI 的对象引用,因此只会在此本地方法执行完成后才会被释放。

posted @ 2022-03-05 15:00  TomStudio  阅读(0)  评论(0)    收藏  举报