Я читал много статей о сборке мусора, и почти во всех статьях рассказывается о куче памяти. поэтому мой вопрос: «сборка мусора собирает память стека, память кучи или и то, и другое».
Собирает ли сборщик мусора память стека, память кучи или и то, и другое?
Ответы (9)
Он собирает кучу памяти. Обычно память стека собирается автоматически, когда путь выполнения достигает конца области. например.:
void fun()
{
int n; // reservation on the stack as part of the activation record
...
} // returning the stack pointer to where it was before entering the scope
На самом деле, в таком языке, как C++, переменные, размещенные в стеке, называются auto
переменными.
Куча памяти.
Сборка мусора — это метод освобождения памяти, которая больше не используется. Иногда часть «больше не используется» сложна. Со стеком, как только функция возвращается, мы можем быть уверены (за исключением ошибки программиста), что локальные переменные больше не используются, поэтому они автоматически освобождаются в это время почти для каждого языка/среды выполнения.
Стек называется «стеком» именно потому, что это зона памяти, которая управляется с помощью «политики стека», также известной как LIFO (последний пришел, первый вышел). Если бы распределение в стеке не было выполнено «стековым способом», оно называлось бы не стеком, а кучей.
Сборка мусора была придумана для того, чтобы справиться с проблемой размещения вещей в куче, т.е. такой, чтобы нельзя было предсказать, какие части будут освобождены первыми. Сборщик мусора предназначен для решения проблем с выделением памяти, когда управления стеком недостаточно.
Стек находится последним в первом выходит, поэтому нет необходимости в сборке мусора.
--исправлено-- ага!
в стеке лежат аргументы вашего метода и локальные переменные. если вы покидаете метод, указатель стека автоматически уменьшается (или увеличивается в зависимости от конкретной реализации). Это справедливо для большинства языков программирования.
сборка мусора, напротив, работает только в куче.
Если вы не используете профилировщик, о котором никто из нас не знает, куча является основной проблемой. Это потому, что большинство людей просто реагируют на то, что им говорит высоко оцененный инструмент. Пожалуйста, дочитайте этот пост до конца, чтобы убедиться, что большинство инструментов профилирования, которые указывают на ошибки статически выделенной памяти, обычно работают правильно. Профилирование должно выходить за рамки простых утечек и сборки мусора.
Позвольте мне привести вам пример в C:
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *am_i_leaking;
am_i_leaking = strdup("Now, that's subjective!");
return 0;
}
Если ОС, на которой запущена эта программа, не освобождает кучу автоматически, значит проблема возникла у меня. Я не могу представить себе современную ОС, которая не делает того, что на самом деле используется.
Теперь давайте посмотрим на это:
char *foo(void)
{
static char bar[1024];
memset(bar, 0, sizeof(bar));
snprintf(bar, sizeof(bar -1), "Do wa diddy diddy dum diddy do");
return bar;
}
Как ваш компилятор выделяет это, зависит от вашего компилятора. Если вы используете его и можете возиться с результатом, вероятно, у вас сломан компилятор. Тем не менее, если у меня есть 100 потоков, одновременно входящих в эту функцию, результат, безусловно, будет хламом, если только мой компилятор волшебным образом не вычислит, что я имею в виду, и не введет взаимное исключение или динамическое распределение без моего беспокойства об этом. , после чего мы вернулись к профилированию кучи.
Короче говоря, в нашей жизни сбор мусора относится к куче. Рассчитывайте на то, что в будущем некоторые из них попытаются «оптимизировать» стек, а затем рассчитывайте на то, что эти усилия станут интерпретируемым языком, который будет востребован кучей генеральных директоров.
Это не означает, что игнорирование ошибок памяти — это хорошо, независимо от того, какое у вас хранилище.
По крайней мере, в java стек будет автоматически дераспределен, когда вы покинете этот кадр стека, поэтому нет необходимости собирать мусор.
Я java-программист, поэтому у меня нет этой проблемы, но на самом деле в C++ (я слышал) вам нужно быть осторожным с этим, потому что вы можете размещать объекты в стеке, и вы можете оставить этот кадр стека, объект будет дераспределен, и вы больше не сможете его использовать и т. д.
Вы не указываете какие-либо конкретные технологии, но их использование довольно типично для разных языков.
Сборщик мусора работает только с управляемой кучей. В одном процессе может быть несколько куч, некоторые из которых не подвергаются сборке мусора.
Переменные, размещенные в стеке, освобождаются при возврате из метода. Сборщик мусора будет использовать эти переменные для поиска активных ссылок, но не будет собирать память.
Сборщик мусора в Java работает только с памятью кучи, а не с памятью стека, из-за основного принципа, по которому работает стек (последний пришел первым). Это объясняет все само по себе. т.е. когда конец области действия функции достигнутый стек автоматически становится пустым.