问题描述
在了解可达性分析法之后,后了解到JVM的minorGC有跨代引用问题
这不经让我感觉到疑惑,如果存在老年代的对象引用,那在从从全部的GCRoot根节点
可达性分析的时候,不是会经过老年代的对象吗?
为什么出现跨代引用问题呢?
问题解答
从全部的GCRoot根节点一步一步进行可达性分析这难道不是FullGC吗?
那minorGC的意义何在?
首先我们要知道JVM对新生代对象的假设是 大部分的新生代对象都是新加入的短命鬼
也就是可以理解成他们大多数都是GCRoot的直接引用或者新加入的直接引用的引用
minorGC的意义是快速的对这一块的区域进行确认垃圾 ,
所以我认为minorGC的可达性分析并不是完全从GCRoot根节点开始一步一步向下
而是
先把新生代对象之间的引用关系理清,
直接查看GCRoot根节点有没有直接引用新生代的对象
有引用链的存活
没有引用链的被认为是垃圾
但这里出现了一个问题 --如果这个新生代对象被老年代的对象引用,并且这个老年代对象不是垃圾那么这个对象就会被误清 这就是跨代引用问题
也就是说出现跨代引用问题的原因是minorGC的可达性分析是直接看新生代对象是不是GCRoot的直接引用而非FUllGC那样一步一步来。
hotpot解决方式探讨:
跨代引用问题的解决方式是把引用新生代对象的老年代区域(记忆集解决到底选择那部分区域的问)直接加入到GCRoot中去,这个时候你一定有一个疑问? 老年代对象也有可能是垃圾呀!!!!!
是的,老年代对象也有可能是垃圾
但是比起垃圾没被清理,我们更害怕的是 不是垃圾的对象 被清理呀!!!!把老年代对象加入GCRoot确保了不是垃圾的对象不会被误清。
而且要记住JVM中对老年代对象的假设:大多老年代对象都存活 也就是在minorGC中可以吧老年代对象视为GCRoot,只会有一小一部分垃圾存活下来
hotpot这种解决方案保证了不是垃圾的对象一定不会被清理,也保证minor GC的高效;
总结
minorGC不一定可以清除新生代的全部垃圾,但可以实现清除新生代中的大部分垃圾和高效率
可以理解为minorGC实际上是 牺牲垃圾清理的一定的准确性来换取了高效