Я понимаю, что утечка памяти в куче происходит из-за объекта, который все еще доступен / доступен в стеке, поэтому G C не может его очистить.
Это только одна из возможных причин утечки памяти. Другое - это наличие нежелательных ссылок в переменных static
. И, возможно, другие, если вы копаете достаточно глубоко. (Например, вы можете создать утечку памяти кучи Java в собственном коде, или неправильно управляя загрузчиками классов или прямыми буферами памяти, или запустив слишком много потоков.)
1) Означает ли это, что все еще существует поток Java, которому принадлежит эта память стека или нет.
Что ж, стек потока Java удаляется при его завершении. Таким образом, если стек существует, это означает, что его поток еще не завершен. Но он может быть запущен, ожидает блокировки или заблокирован в операции ввода-вывода.
Когда поток завершается, любые оставшиеся ссылки, хранящиеся в его стеке, немедленно становятся недоступными. Но технически они стали недоступны, когда завершился вызов метода run()
.
2) Если да, повторный запуск одного и того же потока Java увеличит утечку памяти или повторно использует те же объекты в куча, так как они видны всем потокам?
Если указанная c утечка памяти вызвана потоком, то повторный запуск потока 1 естественным образом приведет к утечке дополнительной памяти. С другой стороны, поскольку завершение потока потока освобождает все его ссылки, если вы повторно запустите поток после его завершения, вы не составной утечка.
Java не "повторно использовать" объекты. Каждый раз, когда вы new
типа (класса или массива), создается новый объект. Всегда.
Объекты в куче видны не всем потокам. Они видны только тем потокам, к которым они доступны.
3) Если нет, происходит ли утечка в памяти кучи и стека, так как объекты в куче должны быть доступны стеку чтобы пережить G C?
Как я уже сказал в начале, существуют способы создать утечку памяти, которая не зависит от стека. Для доступа к объектам нет необходимости ссылаться через стек.
1 - я предполагаю, что речь идет о создании и запуске нового Thread
с таким же или эквивалентным Runnable
как прежде. Технически, Thread
нельзя запустить (запустить) дважды.