cme*_*ren 6 java garbage-collection
摘自Oracle的官方Java教程,请参阅此处的问题2(我的样板文件).
public static void main(String[] args) {
String[] students = new String[10];
String studentName = "Peter Smith";
students[0] = studentName;
studentName = null;
System.out.println(students[0]);
}
Run Code Online (Sandbox Code Playgroud)
答案说,studentName
由于数组students
仍然引用它,因此不符合垃圾收集的条件.然而,最后一行打印"彼得史密斯",所以对我来说,students[0]
引用似乎是错误的studentName
.有人可以解释一下吗?
我想一步一步地借助图解释.
String studentName = "Peter Smith";
Run Code Online (Sandbox Code Playgroud)
在第一行之后,在String池中创建一个String,并且引用名称studentName指向它.
students[0] = studentName;
Run Code Online (Sandbox Code Playgroud)
此时,另一个参考学生[0]指向同一个对象,如下图所示.现在有2个引用指向在内存中创建的同一对象.
studentName = null;
Run Code Online (Sandbox Code Playgroud)
在此之后,studentName的引用将指向null,即它指向没有对象.但是学生[0]的引用仍然指向String对象(Peter Smith)创建的.
显然,在第三个语句之后,一个引用指向null,但是一个引用仍指向创建的Object.因此,该对象不符合垃圾回收的条件.
希望能帮助到你.
更新:对不起,如果我搞乱了变量名称.但我希望你明白这个主意.
您将引用变量(studentName
和students[0]
)与它们引用的对象("Peter Smith")混淆.studentName
并students[0]
均引用String
对象"彼得·史密斯".一旦他们都没有引用"彼得史密斯" - 并假设其他地方没有其他参考 - 该对象将有资格进行垃圾收集.当它们超出范围时,引用本身就会消失.
教程弄错了.没有对象studentName
.studentName
是一个变量,在某一点上,持有对"彼得史密斯"的引用,在另一点上是null
.类似地,students[0]
是一个内存位置数组中的一个元素,它包含对"Peter Smith"(同一个String
对象)的引用.该教程将变量的概念与它们引用的对象混淆.
我可能推测他们这样做是为了避免深入了解内存使用的细节.这是一个高级主题.但他们的解释IMO引起的混乱比它阻止的更多.