对象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 分区

这里写图片描述

原文 http://blog.csdn.net/kkgbn/article/details/44787149

阅读更多

扫码向博主提问

徐刘根

博客专家

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • Java
  • SSM
  • 分布式
  • MySQL
  • 中间件
去开通我的Chat快问
换一批

没有更多推荐了,返回首页