Что происходит с потоком Java во время утечки памяти в куче? - PullRequest
0 голосов
/ 28 апреля 2020

Я понимаю, что утечка памяти в куче происходит из-за объекта, который все еще доступен / доступен в стеке, поэтому G C не может его очистить. Итак, мои вопросы:

  1. Означает ли это, что все еще работает поток Java, которому принадлежит эта память стека или нет?
  2. Если да, повторное выполнение одного и того же потока Java увеличит утечку памяти или повторно использует одни и те же объекты в куче, поскольку они видны всем потокам?
  3. Если нет, происходит ли утечка как в куче, так и в стеке, так как объекты в куче должны быть достижимы стеком, чтобы пережить G C?

I Прошу прощения за эти простые вопросы, но у меня есть проблемы, чтобы найти четкий ответ на них. Спасибо!

1 Ответ

0 голосов
/ 28 апреля 2020

Я понимаю, что утечка памяти в куче происходит из-за объекта, который все еще доступен / доступен в стеке, поэтому G C не может его очистить.

Это только одна из возможных причин утечки памяти. Другое - это наличие нежелательных ссылок в переменных static. И, возможно, другие, если вы копаете достаточно глубоко. (Например, вы можете создать утечку памяти кучи Java в собственном коде, или неправильно управляя загрузчиками классов или прямыми буферами памяти, или запустив слишком много потоков.)

1) Означает ли это, что все еще существует поток Java, которому принадлежит эта память стека или нет.

Что ж, стек потока Java удаляется при его завершении. Таким образом, если стек существует, это означает, что его поток еще не завершен. Но он может быть запущен, ожидает блокировки или заблокирован в операции ввода-вывода.

Когда поток завершается, любые оставшиеся ссылки, хранящиеся в его стеке, немедленно становятся недоступными. Но технически они стали недоступны, когда завершился вызов метода run().

2) Если да, повторный запуск одного и того же потока Java увеличит утечку памяти или повторно использует те же объекты в куча, так как они видны всем потокам?

Если указанная c утечка памяти вызвана потоком, то повторный запуск потока 1 естественным образом приведет к утечке дополнительной памяти. С другой стороны, поскольку завершение потока потока освобождает все его ссылки, если вы повторно запустите поток после его завершения, вы не составной утечка.

Java не "повторно использовать" объекты. Каждый раз, когда вы new типа (класса или массива), создается новый объект. Всегда.

Объекты в куче видны не всем потокам. Они видны только тем потокам, к которым они доступны.

3) Если нет, происходит ли утечка в памяти кучи и стека, так как объекты в куче должны быть доступны стеку чтобы пережить G C?

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


1 - я предполагаю, что речь идет о создании и запуске нового Thread с таким же или эквивалентным Runnable как прежде. Технически, Thread нельзя запустить (запустить) дважды.

...