【发布时间】:2019-10-03 15:39:06
【问题描述】:
请考虑以下代码:
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static List<String> arraylist=new ArrayList<String>();
//add hello n times to the list
public static void add_to_list(int n)
{
if(n==0)
{
return;
}
else
{
String b=new String("hello");
arraylist.add(b);
add_to_list(n-1);
}
}
public static void main(String args[]) throws IOException
{
add_to_list(5);
for(String s:arraylist)
{
System.out.println(s);
}
}
}
我已尝试多次运行此程序,得到的输出与以下内容相同:
hello
hello
hello
hello
hello
我的假设:
- 一旦方法 add_to_list 被执行,字符串 b 就会超出范围
- 我在其范围之外引用了 arraylist 引用索引
- Arraylist 包含方法中创建的字符串的引用。
因此我的问题是:
- 在我打印值之前,Java 收集器是否有可能清理引用?
- 我是不是很幸运,在读取这些值之前 Java 收集器没有运行?
【问题讨论】:
-
垃圾收集器只会收集没有strong引用的对象。
-
@Slaw 你能解释一下什么是强参考吗?
-
variable
b超出范围,但该对象仍然存在并且不符合 GC 条件,因为该列表包含对它的引用。如果该项目从列表中删除,它将有资格获得 GC。 -
@SouravKanta 正确。垃圾收集器是专门设计的,因此您永远看不到它在工作。
-
@SouravKanta 不同之处在于,在 Java 中,除了原语和引用之外,堆栈上实际上不存在任何东西。所有对象都在堆栈外分配。为了补偿将所有内容都堆积到堆上,有一个内存用于池中新创建的对象 - “young gen” - 从中积极地剔除对象。
标签: java