在Java中的双向链表上设置头部和尾部引用是否真的从内存中清除它?
作者:互联网
有一天,我的数据结构课程教授(Java)说,“好吧,伙计们,我们怎样才能从内存中清除这个n元素双向链表?”.我大声说出“将头部和尾部设置为空”.他回答说“好的,但这真的从记忆中清除了吗?”我说“是的,我是这么认为的”.
无论如何,他接着说,由于列表中的节点之间有来回传递,所以它并没有真正从内存中清除它.我想我们正在看这样的事情:
Head Tail
null <-[null/data/node 2]-> <-[node1/data/node3]-> <-[node2/data/node4]-> <-[node3/data/null]->null
让我们假设这是Java中典型的双向链表数据结构,其中Node是一个类(内部或单独的类),DoublyLinkedList类中唯一的实例变量是
Node head;
和
Node tail;
他说这是因为在列表的内部部分中,每个节点都有一个对下一个节点的引用,并且该节点具有对前一个节点的引用.他说在单链表中不会出现这种情况,因为引用只是“单行道”,一旦你失去对第一个引用的引用,它们最终都会被垃圾收集.
当然,课堂上的每个人都分享了他们的观点,但课堂上没有人是我听过的任何人或从中获取编程建议,而且当我在Stack Overflow上提出一个问题与我的教授所说的问题时,我似乎得到了相互矛盾的信息.我.我会说实话,我没有足够的经验来讨论这个问题,但简单地说,我不知道我是否总是相信他所说的一切,因为他在我问过他的一两件事上是错的.
所以,确定
head = null;
和
tail = null;
从内存中清除整个列表?如果是这样,我该怎么验证呢?如果没有,那么摆脱清单的解决方案的一般想法是什么?逐节点删除?请留下您的想法和意见.
解决方法:
你是对的:即使存在循环引用,任何现代JVM都会回收内存(只要它不能从实时引用中访问).这意味着只要没有对其任何节点的实时引用,您的双向链表就会被垃圾收集.
我建议你阅读mark-and-sweep garbage collectors.
基本的想法是垃圾收集器以一堆“roots” (i.e. known live objects)开始并且跟随所有引用链到最后.在此过程中未到达的任何对象都被认为有资格进行垃圾回收,因为程序无法访问它们.
在现代JVM中使用的实际垃圾收集器比这复杂得多,但这应该给你基本的想法.
您的教授可能正在考虑reference counting.虽然某些语言(例如,CPython)确实使用引用计数进行垃圾收集,但这很少是唯一的机制,因为它无法处理循环引用. FWIW,我从未遇到过使用引用计数进行垃圾收集的JVM.
标签:java,doubly-linked-list 来源: https://codeday.me/bug/20190517/1120161.html