以下代码创建一个数组和一个字符串对象。
现在我的问题是
这是我的代码
String[] students = new String[10];
String studentName = "Peter Smith";
students[0] = studentName;
studentName = null;
我认为答案只有一个对象,即students
但根据Oracle docs,Neither object is eligible for garbage collection
我应该如何推断答案?
答案 0 :(得分:10)
代码执行后对这些对象有多少引用?
String[]
的一个引用,可通过表达式students
获得。String
的一个引用,可通过表达式students[0]
获得。为什么?
基本上,答案是对象,而不是变量,可以有资格进行垃圾回收。
在您的情况下,您已将字符串(对象)的引用复制到数组的第一个插槽中。即使您清除(设置为null
)初始变量,同样的对象仍然可以从您的代码中看到,通过其他名称(以及“name”在这里我的意思是“表达式”,如上所述)。这就是字符串仍然不符合垃圾收集的原因。
为了进行比较,请考虑没有第三行的代码:
String[] students = new String[10];
String studentName = "Peter Smith";
studentName = null;
在这种情况下,字符串"Peter Smith"
确实有资格进行垃圾收集,因为您无法通过任何表达式获取它。
(以上所有内容都与Java语言有关,并且不考虑任何可能的JVM优化。)
答案 1 :(得分: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" )
我希望这是有道理的。
答案 2 :(得分:3)
这里"Peter Smith
是一个对象并分配给students[0]
所以它不能被垃圾收集和studentName=null
,它指向什么都没有,所以没有尝试垃圾收集它。
所以,两者都不能被垃圾收集。
答案 3 :(得分:3)
对象可以有多个引用,即使将studentName
的引用设置为null,student[0]
仍然引用了String对象。所以String "Peter Smith"
不能被垃圾收集。
答案 4 :(得分:1)
你是对的students
是一个对象,但它是String数组类型的对象。在数组中,数组的每个元素都可以引用其他对象,第一个元素`students [0]'引用包含“Peter Smith”的字符串对象,这样对象仍然被引用,因此不符合垃圾回收的条件。当学生超出范围并有资格获得GC本身时,字符串对象也将如此。
答案 5 :(得分:1)
students
被实例化然后被更改,因此没有理由收集它,因为我们仍然有一个引用。 studentName
被实例化,然后引用被分配给students
,所以当它在最后一行被解引用时,对象的引用,字符串,仍然存在于数组中,那就是为什么GC没收集任何东西。