4

以下代码创建一个数组和一个字符串对象。

现在我的问题是

  1. 代码执行后存在多少对这些对象的引用?
  2. 为什么?

这是我的代码

String[] students = new String[10];
String studentName = "Peter Smith";
students[0] = studentName;
studentName = null;

我在想答案只有一个对象,即students
但根据Oracle 文档Neither object is eligible for garbage collection

我应该如何推断答案?

4

6 回答 6

10

代码执行后存在多少对这些对象的引用?

  • 一个对 a 的引用String[],可通过表达式获得students
  • 一个对 a 的引用String,可通过表达式获得students[0]

为什么?

本质上,答案是对象,而不是变量,可以有资格进行垃圾收集。

在您的情况下,您已将字符串的引用(它是一个对象)复制到数组的第一个插槽中。即使在您清除(设置为null)初始变量之后,相同的对象仍然可以从您的代码中以另一个名称可见(这里的“名称”是指“表达式”,如上所述)。这就是为什么字符串仍然不符合垃圾回收条件的原因。


为了比较,请考虑没有第三行的代码:

String[] students = new String[10];
String studentName = "Peter Smith";
studentName = null;

在这种情况下,字符串"Peter Smith"确实可以像您期望的那样进行垃圾回收,因为它不再可以通过任何表达式获得。


(以上所有内容都与 Java 语言有关,任何可能的 JVM 优化都放在一边。)

于 2013-06-02T13:22:28.973 回答
4
String[] students = new String[10];
// 1. One object (array of String, 1 reference to it - students)
String studentName = "Peter Smith";
// 2. Two objects (array from (1), string 'Petter Smith'), two references 
// (students from (1), studentName that refers String object )
students[0] = studentName;
// 3. Two objects (the same as (2)), 3 references ( in addition to references (2) 
// first element of students array refers to the same object as studentName
studentName = null;
// Two objects (Array and String "Peter Smith"), two references (one is array, 
// another is students[0] 
// Neither of them can be marked for garbage collection at this point 
// (Array and String "Peter Smith" )

我希望这是有道理的。

于 2013-06-02T13:20:33.480 回答
3

"Peter Smith是一个对象并分配给它,students[0]因此它不能被垃圾收集,并且studentName=null它没有指向任何东西,所以不要尝试垃圾收集它。

因此,两者都不能被垃圾收集。

于 2013-06-02T13:14:24.530 回答
3

一个对象可以有多个引用,即使您将引用设置studentName为 null,String 对象仍被 引用student[0]。所以字符串"Peter Smith"不能被垃圾收集。

于 2013-06-02T13:18:40.060 回答
1

你是对的,它students是一个对象,但它是一个字符串数组类型的对象。在数组中,数组的每个元素都可以引用其他对象,并且第一个元素 `students[0]' 正在引用包含“Peter Smith”的字符串对象,因此该对象仍被引用,因此不符合垃圾回收条件。当学生超出范围并有资格获得 GC 本身时,字符串对象也会。

于 2013-06-02T13:16:47.110 回答
1

students被实例化然后改变,所以没有理由收集它,因为我们仍然有一个引用。studentName被实例化,然后引用被分配给students,所以当它在最后一行被取消引用时,对对象的引用,字符串,仍然存在于数组中,这就是 GC 没有收集任何内容的原因。

于 2013-06-02T13:17:29.613 回答