Стек собран "мусор" в Java?

Память "кучи" собрана "мусор" в Java.

Стек собран "мусор" также?

Как стековая память исправлена?

55
задан Björn Lindqvist 10 September 2016 в 02:55
поделиться

8 ответов

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

0
ответ дан 7 November 2019 в 07:22
поделиться

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

Таким образом, стек не собирает мусор таким же образом, как куча, но стек представляет собой форму автоматического управления памятью (которое предшествует сборке мусора).

Более подробный ответ дан Томасом Порнином , подробнее см. В нем.

37
ответ дан 7 November 2019 в 07:22
поделиться

В Java стек не собирается в мусор.

Стек, выделенный для данного вызова метода, освобождается, когда метод возвращается. Поскольку это очень простая структура LIFO, сборка мусора не нужна.

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

28
ответ дан 7 November 2019 в 07:22
поделиться

Стек мог быть удален сборщиком мусора. Однако в большинстве реализаций JVM он обрабатывается как «стек», что по определению исключает сборку мусора.

То, что мы называем стеком, - это совокупность контекстов активации метода : для каждого вызванного метода это концептуальная структура, которая содержит аргументы метода, локальные переменные, скрытый указатель на контекст для вызова метод и слот для сохранения указателя инструкции. Контекст активации недоступен как таковой из самого языка Java. Контекст становится бесполезным, когда метод завершается (с возвратом или из-за сгенерированного исключения). Бывает так, что когда метод A вызывает метод B, гарантируется, что, когда A восстанавливает контроль, контекст для B становится бесполезным. Это означает, что время жизни контекста для B является поддиапазоном времени жизни контекста для A. Следовательно, контексты активации (для данного потока) могут быть распределены с помощью дисциплины LIFO («Последний вошел, первый вышел»).Проще говоря, стек: новый контекст активации помещается поверх стека контекстов, и контекст сверху будет удален первым.

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

Теперь ничто не мешает реализации JVM поступать иначе, например выделение контекстов активации в куче и их сбор сборщиком мусора. Обычно это не делается на виртуальных машинах Java, поскольку выделение стека происходит быстрее. Но некоторые другие языки должны делать такие вещи, в первую очередь те, которые играют с продолжениями , все еще используя GC (например, Scheme и ее call-with-current-continue ), потому что такие игры нарушают правило LIFO, описанное выше.

14
ответ дан 7 November 2019 в 07:22
поделиться

Стековая часть памяти работает так же, как и "стек". Я знаю, что это звучит плохо, но именно так это и работает. Данные добавляются сверху, друг на друга (pushed onto the stack) и автоматически удаляются сверху (popped off the stack) по мере выполнения вашей программы. Она не собирается в мусор - и в этом нет необходимости, поскольку эта память автоматически освобождается, когда данные выгружаются из стека. Когда я говорю "освобождается", я не имею в виду, что она деаллоцируется - просто место в памяти стека, где будут храниться следующие данные, уменьшается по мере того, как данные сбрасываются.

Конечно, это не означает, что вам не нужно беспокоиться о стеке. Если вы много раз запускаете рекурсивную функцию, она в конце концов использует все пространство стека. То же самое, если вы вызываете много функций, особенно если у них много параметров и/или локальных переменных.

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

8
ответ дан 7 November 2019 в 07:22
поделиться

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

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

Обычно это не имеет значения, если вы не используете финализаторы (или предположительно Ссылка s). В этом случае вы должны быть осторожны и использовать locks / volatile для обеспечения отношения происходит до .

Когда потоки останавливаются, обычно освобождается весь стек.

1
ответ дан 7 November 2019 в 07:22
поделиться

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

1
ответ дан 7 November 2019 в 07:22
поделиться

Если вы ссылаетесь на память, используемую в стеке, это не сборщик мусора.
Виртуальная машина Java использует явные инструкции байт-кода для резервирования и освобождения памяти в стеке. Эти инструкции генерируются компилятором и управляют временем жизни таких примитивов, как int, boolean, double и объектные ссылки на куча.
Были планы реализовать так называемую оптимизацию хвостового вызова, которая удаляла бы некоторые записи из стека, как только станет известно, что они больше не используются, но я не знаю ни одной jvm, которая уже поддерживает это.
Итак, нет никакой сборки мусора для самого стека, только компилятор сгенерировал инструкции push и pop для управления использованием памяти.

Стек сам по себе является частью потока. Стек выделяется при создании объекта потока и сборке мусора после завершения потока и отсутствия ссылок на объект потока.

4
ответ дан 7 November 2019 в 07:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: