2014-09-30 4 views
0

Мне был задан вопрос о сборе мусора в одном интервью.Java: сбор мусора

Ниже приведен фрагмент кода.

List<String> a=new ArrayList<String>(); 
    a.add("one"); 
    a.add("two"); 
    a.add("three"); 
    a.add("four"); 

HashSet<String> h=new HashSet<String>(); 
h.add("four"); 
h.add("five"); 
h.add("six"); 

h.addAll(a); 
a=null; 

Вопрос: сколько объектов имеют право для сбора мусора>

Пожалуйста, объясните.

+1

ИМО единственный правильный ответ: * невозможно сказать *. :-) Мы не знаем, сколько объектов создается внутри 'String',' HashSet' и 'ArrayList'. – NPE

+0

Еще одна причина, по которой невозможно сказать, заключается в том, что ничего не говорится о точном времени, когда вопрос должен быть оценен. Сразу после последнего назначения или когда метод закончен? –

+0

@NPE На самом деле, мы делаем, по крайней мере, с openjdk. Единственным видимым для пользователя объектом GC является объект ArrayList, который [назначен один] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/ util/ArrayList.java # ArrayList.0DEFAULT_CAPACITY) 'Object [10]'. Так что ответ два. – maaartinus

ответ

3

Общий ответ для видимых объектов в локальной области: только ArrayList. HashSet доступен через локальную переменную h, а строки доступны через HashSet. Доступны только объекты, недоступные для сбора мусора.

Примечания:

  1. Строковые литералы конкретно могут быть выделены в строке пула, как указано в комментарии. В этом случае эти объекты не будут иметь права на сбор мусора.

  2. Объекты, которые доступны только по специальным типам ссылок (например, слабые ссылки), могут по-прежнему иметь право на участие.

  3. Возьмите все это с солью, потому что это теоретический вопрос интервью по предмету, который на практике сложный. Например, вы не знаете, какие другие объекты выделены за кулисами. Или может быть агрессивный GC, который собирает объекты, даже если они (с точки зрения языка) достижимы, если это может доказать, что их нет другого использования.

+1

Собственно, строки будут помещены в пул строк (литералы), так что вторая часть вашего ответа частично действительна. – TheLostMind

+1

@TheLostMind в зависимости от версии строк JVM будет либо в пуле строк в куче пермг (никогда не собирать мусор), либо в обычной куче (с java 7). В обычной куче они будут собираться, если они больше не требуются. – SimY4

+1

@ SimY4 - Я знаю.Вот почему я не проголосовал или сказал, что он неправ. Я просто указывал, что он * частично * действителен. – TheLostMind

1
List<String> a=new ArrayList<String>(); 
    a.add("one"); --> "one" is added to the String constants pool and the reference is added to th arraylist 
    a.add("two"); --> same as above 
    a.add("three"); --> same as above 
    a.add("four"); --> same as above 
// 4 String literals in string pool, 4 references to them in the array list. 

HashSet<String> h=new HashSet<String>(); 
h.add("four");--> "four" is added to the String constants pool and the reference is added to the hashSet 
h.add("five"); 
h.add("six"); 
// even if you don't use h.addAll(), only 1 object i.e, a will be ready for GC once you set it to null because String literals in the constant pool cannot get GCed. 
//h.addAll(a); 
a=null; 


PS : System.out.println(a.get(0) == "one"); returns true . same applies to elements of HashSet 
1

Поскольку у вас есть

a = null; 

и если нет никаких других объектов, проведение ссылки на список или его содержащих объекты, он будет иметь право на сбор мусора. Кроме того, знайте, что нет никакой гарантии, когда JVM фактически запустит сбор мусора на нем и освободит память.

Смежные вопросы