может ли какой-нибудь неиспользованный объект убежать из сборщика мусора? - PullRequest
3 голосов
/ 25 января 2010

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

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

Ответы [ 11 ]

8 голосов
/ 25 января 2010

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

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

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

Редактировать : в ответ на ваш комментарий, если объект действительно ни на что не ссылается, он будет возвращен во время сборки мусора (при условии, что вы используете последнюю версию JVM от Sun; я не могу говорить по отношению к другим реализациям). Причина в следующем: все объекты расположены в куче. Когда должен произойти GC, JVM следует всем ссылкам, чтобы «пометить» объекты, которые, как она знает, достижимы - эти объекты затем перемещаются в другую, чистую область. Старая область тогда считается свободной памятью. Все, что не может быть найдено по ссылке, не может быть перемещено. Дело в том, что GC не нужно «находить» объекты, на которые нет ссылок. Во всяком случае, я бы больше беспокоился об объектах, на которые все еще ссылаются, когда они не предназначены, что приведет к утечкам памяти.

6 голосов
/ 25 января 2010

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

2 голосов
/ 25 января 2010

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

Система CG очень хороша в поиске объектов, на которые нет ссылок. Есть крошечный, крошечный шанс, что в итоге вы сохраните странное сочетание ссылок, при котором сборщик мусора не может точно решить, на какой объект больше нет ссылок или нет. Но это было бы ошибкой в ​​системе CG, и вам не о чем беспокоиться во время кодирования.

2 голосов
/ 25 января 2010

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

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

Если вы хотите узнать все подробности, ознакомьтесь с документацией Sun gc .

1 голос
/ 26 января 2010

Сборщик мусора в конечном итоге восстановит все недоступные объекты. Обратите внимание на «в конце концов»: это может занять некоторое время. Вы можете вызвать проблему с помощью System.gc(), но это редко хорошая идея (если использовать ее по своему усмотрению, производительность может снизиться).

Что может случиться, так это то, что объект «не используется» (как в случае: приложение больше не будет его использовать), хотя он по-прежнему «достижим» (GC может найти путь ссылок из одного из своих корней - статических полей). локальные переменные - к объекту). Если вы не слишком запутались в своих объектах и ​​структурах, вы не столкнетесь с такими ситуациями. Практическое правило будет таким: если приложение, кажется, занимает слишком много оперативной памяти, запустите на нем профилировщик; если тысячи экземпляров одного и того же класса накопились без видимой причины, то где-то может быть какой-то подозрительный код. Исправление часто включает в себя явное задание поля для null, чтобы избежать ссылки на объект слишком долго.

1 голос
/ 25 января 2010

Сборка мусора намеренно дает мало гарантий относительно КОГДА объектов. Если память никогда не становится слишком тесной, вполне возможно, что объект, на который нет ссылок, не будет собран к моменту завершения программы.

1 голос
/ 25 января 2010

Да; представьте что-то вроде этого:

Foo foo = new Foo();

// do some work here

while(1) {};

foo.someOp(); // if this is the only reference to foo,
// it's theoreticaly impossible to reach here, so it
// should be GC-ed, but all GC systems I know of will
// not Gc it

Я использую определение: garbage = объект, который никогда не может быть достигнут ни при каком выполнении кода.

0 голосов
/ 26 февраля 2012

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

Просто для полноты, мне в голову приходят две хитрые ситуации [с которыми вы вряд ли столкнетесь]:

  • Ошибки в JVM или код сборщика мусора
  • Так называемые невидимые ссылки - они редко имеют значение, но мне пришлось принимать их во внимание один или два раза в течение последних 5 лет в чувствительном к производительности приложении, над которым я работаю
0 голосов
/ 12 мая 2010

Мой совет - не беспокойтесь об этом.

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

0 голосов
/ 25 января 2010

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

Это сказало: «В теории нет разницы между теорией и практикой, на практике, есть». В некоторых, в основном старых, сборщиках мусора, если определению объекта удается достичь постоянного поколения, тогда он больше не будет собирать мусор ни при каких обстоятельствах. Это относится только к загруженным определениям классов, но не к обычным объектам, которым предоставлен статус владения.

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

На практике это очень маловероятное событие, и вам не нужно об этом беспокоиться. Если вы сильно обеспокоены производительностью, то создание большого количества «долгоживущих» объектов, то есть тех, которые избегают «escape-анализа», создаст дополнительную работу для сборщика мусора. Однако для 99,99% кодеров это не проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...