也许我现在疯了,但我对范围、内存分配或垃圾收集有疑问。
类LinkedIntList有一个私有字段front,它是ListNode类型的变量(第4行)。链表的其余部分是通过调用add()函数(第29行)构建的。
问题:当返回add()时(第39行),在add()中由new创建的ListNode是否超出了作用域,并且应该被垃圾收集?还是因为前面的链子指向他们,所以他们被保留了?
1 // Simple first version of LinkedIntList with just a constructor
2 // and methods for add and toString.
3
4 public class LinkedIntList {
5 private ListNode front; // first value in the list
6
7 // post: constructs an empty list
8 public LinkedIntList() {
9 front = null;
10 }
11
//....
//....
28 // post: appends the given value to the end of the list
29 public void add(int value) {
30 if (front == null) {
31 front = new ListNode(value);
32 } else {
33 ListNode current = front;
34 while (current.next != null) {
35 current = current.next;
36 }
37 current.next = new ListNode(value);
38 }
39 }
40 }
当add()返回时,创建并附加到列表的ListNode被保留,因为它是由前面链式指向的。在这种情况下,当函数返回(类似于值)时,按值传递给函数的参数将超出范围,并且不能从外部引用。但是ListNode是一个新的Object创建,它在内存中被分配了空间,即使函数返回也会保留。
当对某个内存位置的引用丢失时,垃圾回收就完成了。当您的程序运行时,您的引用将是活动的,因此不能进行垃圾收集。
垃圾收集器不会收集对象,直到有一个对它的"实时"引用,即直到它可以访问(即循环依赖关系不计算在内)。您可能需要查看标记和扫描算法。
您的ListNode是列表的一个元素,因此根据定义,它是不可访问的(只要您保留对列表头的引用)。
我建议你阅读这一章,这是迄今为止我发现的对垃圾收集技术最清晰的解释之一。