В какой именно точке находится объект, доступный для сбора мусора?

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

public void someMethod() {
   MyObject myObject = new MyObject();
   myObject.doSomething();  //last use of myObject in this scope
   doAnotherThing();
   andEvenMoreThings();
}

Итак, мой вопрос: будет ли myObject доступным для сбора мусора после myObject.doSomething(), который является последним использованием этого объекта, или после завершения someMethod(), где он выходит из области видимости? То есть является ли сборка мусора достаточно умной, чтобы увидеть, что хотя локальная переменная все еще находится в области видимости, она не будет использоваться остальной частью кода?

Ответ 1

"Где он выходит из сферы действия"

public void someMethod() {
   MyObject myObject = new MyObject();
   myObject.doSomething();  //last use of myObject in this scope
   myObject = null; //Now available for gc
   doAnotherThing();
   andEvenMoreThings();
}

Ответ 2

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

Если вы используете более позднюю версию Java, тогда JVisualVm входит в стандартную комплектацию.

Если вы находитесь в окнах и у вас установлен JAVA_HOME

% JAVA_HOME%/bin/jvisualvm

Это запустит профайлер, и вы увидите, какие объекты собираются, а какие нет. По-моему, это важная часть того, чтобы быть программистом и его забавой найти утечки памяти.

Надеюсь, что это поможет

Ответ 3

Btw в более позднем java 6, существует тип анализа утечки, где JVM может узнать, что ваш экземпляр MyObject не оставляет метод, поэтому он даже может полностью разместить его на стеке, и вам вообще не понадобится GC.

Ответ 4

Итак, мой вопрос: будет ли доступен myObject для сбора мусора после myObject.doSomething(), который является последним использованием этого объекта или после завершения someMethod(), где он выходит из области видимости?

Первый.

т.е. является ли сборка мусора достаточно умной, чтобы увидеть, что хотя локальная переменная все еще находится в области видимости, она не будет использоваться остальной частью кода?

Масштаб не отображается в GC, который видит только регистры, стеки, глобальные переменные и ссылки из блоков кучи в другие блоки кучи. Таким образом, объем не имеет значения.

Ответ 5

После того, как локальная область недоступна. поскольку объект может быть повторно использован и может жить в локальном масштабе. то есть. он помечен для gc. но не на самом деле gc'ed.

Ответ 6

Оптимизация кода, вероятно, заметит, где используется последнее использование myObject, и сделать его доступным для коллекции мусора там, однако технически это будет до тех пор, пока переменная больше не будет ссылаться на него (назначая что-то еще) или гаснет области.