什么是GC ROOT?都有哪些GC ROOT?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是GC ROOT?都有哪些GC ROOT?相关的知识,希望对你有一定的参考价值。

参考技术A 上⾯提到的标记的算法,怎么标记⼀个对象是否存活?简单的通过引⽤计数法,给对象设置⼀个引⽤计数器,每当有⼀个地⽅引⽤他,就给计数器+1,反之则计数器-1,但是这个简单的算法⽆法解决循环引⽤的问题。

Java通过可达性分析算法来达到标记存活对象的⽬的,定义⼀系列的GC ROOT为起点,从起点开始向下开始搜索,搜索⾛过的路径称为引⽤链,当⼀个对象到GC ROOT没有任何引⽤链相连的话,则对象可以判定是可以被回收的。

⽽可以作为GC ROOT的对象包括:

1. 栈中引⽤的对象

2. 静态变量、常量引⽤的对象

3. 本地⽅法栈native⽅法引⽤的对象

JVM对象A和B循环引用,最后会不会不被GC回收?-------关于Java的GC机制


①首先说一下,GC里边在JVM其中是使用的ROOT算法,ROOT算法,什么称作为ROOT呢,就是说类的静态成员,静态成员就是static修饰的那种,是“根”的一个,根还包含方法中的成员变量。仅仅有成员或对象不挂在根上,GC的时候就可能把他们搞掉,这里提到的循环引用,就看这个循环引用是否挂在根上,假设挂在根上。假设这个根还被JVM的Java代码所运行的话,就不会GC掉,假设说这个根已经被释放掉了。这个对象不挂在跟上了。那个这个对象就会被GC掉。


②说一下根搜索算法,ROOTS,这个算法,那些在Java里会被觉得是根呢,在我印象里通常是static修饰的类成员,比方说静态字段,这样的字段引用的对象被称为根。仅仅要类在POOL区里不被卸载。一直在堆里,类对象仅仅要没被回收掉,他引用的对象就不会被GC。


③再说还有一种情况。方法中的栈,栈中有他的栈成员 Integer  a = XXX,当方法没有被释放。没有出栈的时候,方法没有被弹出的时候,那Integer a 所引用的对象也是不会被回收的,在什么情况下回收呢,就是这个对象没有挂在根上。就会被回收。


④我们回到标题的问题,这个循环引用是否被回收,就看这个循环引用是否挂在根上,A引用B,B引用A,A和B并没有挂在某个内存元和根上,当他们的生命周期结束的时候。这两个对象都有可能被回收。


⑥详细回收的机制,就比較复杂了。每次GC的时候。对要被回收的对象标记一次。比方说会有个计数器每次+1,+1,+1。每次GC的时候就+1一次。当对象达到默认值了。比方说好像15次吧,在新生带创建的对象达到15次了就会被达到老年带里去,而老年代对象的回收的频率和新生带回收的频率是不一样的,能够细致看下图中pool里的分区。了解他们的执行机制。




注:JVM heap分区块

Generation代
 - YongGeneration/NewGeneration:新生代。在Eden/S0/S1的存活的对象。

 - OldGeneration:老年代。在Tenured区存活的对象。
 - PermanentGeneration:永久代。
Space 区
 - Eden:伊甸园区。是新生代的一个区。


 - Survivor:幸存区,属于新生代,为了复制算法的须要。一般分成大小相等的两个区(S0/S1或者From/To)。

 - Tenured:存放老年代的区域。
 - Permanent:终身区。



 
下图:Hotspot 的 Heap 分区

以上是关于什么是GC ROOT?都有哪些GC ROOT?的主要内容,如果未能解决你的问题,请参考以下文章

JVMGC 可达性分析中哪些算是GC ROOT?

GC垃圾回收

什么是 gc root

GC Root

GC Root

JVM对象A和B循环引用,最后会不会不被GC回收?-------关于Java的GC机制