今天在看LinkedList源码的时候发现clear和unlink源码都对Node的前后和itme进行了分别置空,我之前的想法是直接把所有的Node本身直接置空,x.prev=null和x.next=null,直接x = null也可以使得所有节点为空啊
但在参考了很多资料后发现,如果单纯的x=null而不x.prev=null和x.next=null,可能不会正常触发GC,事情远远没有那么简单…
阅读本文需要有JVM垃圾回收机制的知识储备
参考资料:
https://www.iteye.com/problems/71569
https://www.bilibili.com/video/BV1AE411E7uj?p=1
https://www.bilibili.com/video/BV1yE411Z7AP?spm_id_from=333.999.0.0
https://www.cnblogs.com/chenpt/p/9803298.html
https://www.iteye.com/problems/71569
https://codingdict.com/questions/113892
https://www.cnblogs.com/dmzna/archive/2020/05/18/12913458.html
https://www.cnblogs.com/shouyaya/p/13524476.html
https://blog.csdn.net/mccand1234/article/details/52078645
https://blog.csdn.net/qq_41701956/article/details/81664921
https://blog.csdn.net/yubujian_l/article/details/80804708
例如clear的源码
x.next = null,即表示下一个节点对象=null,为什么还要分成3步写来把属性=null呢?为什么不仅仅是把首尾节点=null让链表找不到入口呢?
注释翻译:
- is sure to free memory even if there is a reachable Iterator 即便是有迭代器指针此时正在访问中间的节点,也会置空。
- helps a generational GC if the discarded nodes inhabit more than one generation有多个节点时,这样做有助于GC垃圾回收
注解解读:
第一个
如果仅仅是把首尾置空,中间的链表虽然找不到首尾入口,但若此时:
- 有迭代器正好访问到中间,取到了中间的node对象
- 中间的某个node已被强引用
第二个
倘若JDK版本在8以上,可以忽略这一条,但老版本的gc机制,所用的垃圾收集器可能使用的算法是引用计数器算法,该算法不能解决相互引用情况下的垃圾回收
例如:没有迭代器访问,中间节点对象也没有被强引用,但是他们之间是互相调用的,引用计数器算法不能回收这样的对象,即便是他们没有入口
而在JDK的流行高版本中一般不使用引用计数器算法,而使用可达性分析算法,当他们都没有被强引用时,便没有了GC Roots根对象,因此会被垃圾回收
综上:第二个注释“help GC”所表达的含义是防止因为JDK版本低,垃圾回收算法所导致的“无法回收循环引用”的情况
同样 对于remove方法调用了unlink,注解也说了help GC