2013-09-05 2 views
1

Я читаю об управлении памятью в JVM и что если объект больше не ссылается на него, это сбор мусора. позволяет сказать, у меня есть программакак сборка мусора в отношении строк в Java?

public test { 
    public static void main(String[ ] args) { 
     String name = "hello"; 
     for (int i =0 ; i < 5; i++) { 
     System.out.println(i); 
     } 
    } 
} 

Как вы можете видеть, String name нигде не используется, поэтому его ссылка хранится через вне и не мусор.

теперь у меня есть,

String name = "hello" 
    String name2 = name.substring(1,4)//"ell" 

здесь, ссылка на hello должен присутствовать всегда, и не может быть мусора, так как name2 использует его.

поэтому, когда эти String или любые objects получают сбор мусора, которые имеют ссылки, но устарели, то есть больше не используются в коде?

Я вижу один сценарий, когда обрезка массива вызывает утечку памяти и, следовательно, установление ссылки на нуль - это хороший способ сбрасывать эти устаревшие ссылки.

+0

Текущие версии Java не содержат ссылки на 'name' в' name2', и в этом случае 'name' можно свободно собирать. Кроме того, что вы подразумеваете под «обрезкой массива»? –

+0

@LouisWasserman Думаю, он говорит об исключении неиспользуемых записей. – chrylis

ответ

1

Я вижу один сценарий, в котором уравновешивать вниз массив вызывает утечку памяти и, следовательно, установив его ссылку на нуль является хорошим способом для мусора собирать эти устаревшие ссылки.

Строки являются ссылочными типами, поэтому все правила ссылочных типов в отношении сбора мусора относятся к строкам. JVM также может сделать некоторые оптимизации для строковых литералов, но если вы беспокоитесь об этом, то, вероятно, вы слишком много думаете.

Когда JVM собирает неопубликованные объекты?

Единственный ответ, который имеет значение: вы не можете сказать, и это не нужно никогда, но если это так, вы не можете знать, когда это будет. Вы никогда не должны писать Java-код вокруг детерминированной коллекции мусора. Это не нужно и чревато уродством.

Говоря в целом, если вы ограничиваете свои ссылочные переменные (включая массивы или коллекции ссылочных типов) до самого узкого места, то вам уже предстоит пройти долгий путь, чтобы не беспокоиться о утечке памяти. Долговечные ссылочные типы потребуют некоторой осторожности и кормления.

«Обрезка» массивы (элементы массива Снятие ссылки присвоив null к ним) является ТОЛЬКО необходимо в частном случае, когда массив представляет свою собственную систему для управления памятью, например. если вы создаете свой собственный кеш или очередь объектов.

Поскольку JVM не может знать, что ваш массив «управляет памятью», он не может собирать неиспользуемые объекты в нем, которые по-прежнему ссылаются, но истекли. В тех случаях, когда массив представляет вашу собственную систему для управления памятью, вы должны назначить null элементам массива, чьи объекты истекли (например, выскочил из очереди, J. Bloch, Essential Java, 2nd Ed.).

+0

, когда речь идет о области видимости, как только область объекта завершена (с {}), являются ссылками к нему теряется ??? – eagertoLearn

+0

Как только переменная выходит из сферы действия, она перестает существовать. Когда ссылочная переменная выходит за пределы области видимости, ее ссылка немедленно теряется. Если объект, на который ссылается указанная переменная, не ссылается ни на какое другое место в приложении, он автоматически становится «подходящим для сбора мусора». В Visual Basic 5.0 необходимо было тщательно вывести опорные переменные «null», чтобы предотвратить утечку памяти, но это не нужно в Java и считается плохой практикой, особенно. если переменные скоро будут выходить за рамки. – scottb

+0

Скажите, что у вас есть массив ссылочных типов. Массив сам по себе является ссылочным типом. Если массив ссылается только на одну переменную в приложении -AND- объекты, на которые ссылается массив, не ссылаются ни на какое другое место ... тогда, когда ссылочная переменная выходит за пределы области действия, массив и все его объекты автоматически становятся для сбора мусора. – scottb

0

Каждая переменная в Java имеет область действия: кусок кода, в течение которого определяется переменная. Объем локальной переменной, такой как name в вашем примере, находится между скобками {}, в котором находится. Таким образом, переменная name будет определена, когда поток достигнет объявления String name = "hello";, и будет сохранен до тех пор, пока метод main не будет закончен (потому что тогда скобки, в которых была переменная, закрыты).

Струны - это другая история, чем другие переменные. Строки кэшируются внутри и на самом деле не могут быть доступны для сборщика мусора.

1

Технически, JVM не требуется для сбора мусора объектов . На практике они обычно появляются через некоторое время после того, как последняя ссылка исчезнет и освободит память.

Во-первых, имейте в виду, что константы всегда будут вокруг. Даже если вы назначаете новое значение name, система по-прежнему имеет копию "hello", хранящуюся в классе, который будет использоваться повторно каждый раз, когда вы нажимаете этот оператор инициализатора.

Однако, не путайте использование какого-либо объекта для какого-то вычисления с сохранением ссылки на него навсегда. В вашем втором примере, в то время как "hello" фактически хранится, это только потому, что он живет в постоянном пуле; name2 не имеет никакого «удерживания» на нем, который хранит его в памяти. Вызов substring выполняется и заканчивается, и нет никакого вечного удержания на name. (Фактическая реализация в JVM Oracle разделяет базовый char[], но это зависит от реализации.)

Очистка массивов - хорошая практика, потому что для них распространено долгое время и повторное использование. Если весь массив получает собранный мусор, ссылки, которые он содержит, стираются (и их объекты мусора собираются, если они были последними).

+0

, когда вы говорите, что «константы всегда будут вокруг», означает ли это, если у меня есть 'public final Integer COUNT = 100', значит, объект Integer остается навсегда? – eagertoLearn

+0

Да. На самом деле, даже если у вас есть только инициализатор поля ('private Integer count = 0;'), объект Integer останется там, пока сам класс находится в области видимости. (На самом деле, в JVM на полных компьютерах «Integer's for -128..127 всегда все равно поддерживается для скорости.) – chrylis

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