系统相关
首页 > 系统相关> > 在Java中的双向链表上设置头部和尾部引用是否真的从内存中清除它?

在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