Утечки памяти всегда нужен долгоживущий объект? - PullRequest
1 голос
/ 12 сентября 2009

Является ли это утверждение истинным, ложным или плохо сформулированным:

"В Java утечки памяти всегда должны быть как-то связаны с долгоживущим объектом."

В этом контексте я имею в виду просто обычные объекты, а не системные ресурсы в целом (дескрипторы файлов и т. Д.).

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

Ответы [ 7 ]

10 голосов
/ 12 сентября 2009

Ложная.

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

2 голосов
/ 12 сентября 2009

"В Java утечки памяти всегда должны быть как-то связаны с долгоживущим объектом."

Долгоживущий объект - это Синглтон, или что-то, что будет жить до тех пор, пока приложение работает.

Мы можем немного перевернуть утверждение и сформулировать его в форме вопроса. Вы можете спросить:

Возможно ли иметь утечки памяти в приложении Java, которые не связаны с Singleton или другим основным компонентом (который является долгоживущим по конструкции)?

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

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

Чтобы ответить на это, kdgregory опубликовал в своем блоге статью под названием « Справочные объекты Java или« Как я научился прекращать беспокоиться и любить OutOfMemoryError »* »:

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

2 голосов
/ 12 сентября 2009

утверждение верное, но плохо сформулированное ИМХО. Утечки памяти возникают в результате того, что на объекты все еще ссылаются после того, как они больше не нужны.

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

Интересная статья здесь .

1 голос
/ 12 сентября 2009

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

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

0 голосов
/ 12 сентября 2009

Сначала некоторые вещи, которые нужно установить:

  • На объекты ссылаются из других объектов, и вся работающая программа может быть визуализирована как граф объектов, ссылающихся на другие объекты.
  • По определению, объекты могут собираться мусором, если к ним не может получить доступ текущий поток.
  • Можно создать приложение, намеренно или случайно, которое многократно создает объекты, а затем никогда не позволяет этим объектам собирать мусор. Делайте это достаточно часто в долго работающей программе, и у вас будет заметная утечка памяти.

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

На самом деле, сказать, что утечки памяти всегда связаны с "обычным" долгоживущим объектом - я бы сказал, ложным. Но все еще вводит в заблуждение, как указано выше.

0 голосов
/ 12 сентября 2009

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

Было бы более полезно сказать, ПОЧЕМУ объекты долговечны.

Если вы пишете статью или что-то в этом роде, я бы описал «корни» дерева объектов, которые приводят к сохранению объектов.

К ним относятся:

  • Временные переменные в стеке (любого потока)
  • Статические переменные (из любого класса)
  • Специальные ссылки из нативного кода JNI

Я верю, что есть и другие документы, которые я скопировал из старого. Я знаю, что RMI может содержать ссылки, которые не возвращаются (возможно, подпадает под ту пулю "JNI")

0 голосов
/ 12 сентября 2009

В зависимости от специфики долгоживущих и включения / исключения ошибок JRE, а также значения утечки памяти (как насчет утечек памяти только для половины времени жизни приложения?), А также некоторых особых случаев сборщика мусора (за что G1 должен улучшить ситуацию) и т. д. и т. д. *

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

Конечно, можно сказать без какой-либо ссылки на стек, которая в конечном итоге зависит от времени выполнения main или какой-либо другой корневой ссылки где-либо, ничего не существует; но с такой семантикой вопрос становится бессмысленным. Это все равно что сказать, что без компьютера я не могу запускать приложения Java. Ура, выиграл цену 0 $.

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