Это вторая часть серии «Сборщик мусора».

В любом языке программирования в основном существует три типа распределения:

Статический тип распределения. Статический тип распределения существует с 1950-х годов. Это самый быстрый способ выделить переменные, поскольку статическое распределение выполняется во время компиляции программы.

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

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

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

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

Держите лошадей !, Избавимся ли мы от проблемы структур данных фиксированного размера с типами, выделенными стеком? НЕТ!

Компилятор все еще должен знать размер структуры данных во время компиляции !! но почему? Я напишу об этом отдельную статью. Но на данный момент просто помните, что компилятору требуется размер базовой структуры данных во время выделения стека.

Более того, есть одна серьезная проблема с выделенными типами Stack. Когда вводится распределение времени выполнения, устойчивость стека уменьшается из-за вероятности переполнения стека. И это одна из основных проблем с типами, размещенными в стеке.

Тип с выделением кучи: проблемы, возникающие при использовании типов, выделенных статическим и стековым, можно в некоторой степени решить с помощью объектов типа, выделенного кучей (Да! Объекты с выделением кучи работают медленнее, мы рассмотрим это в другой статье) .

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

Благодаря преимуществу использования пространства памяти по запросу, мы получаем гибкость, заключающуюся в наличии структур данных переменного типа, которые могут расти во время выполнения программы (информация о размере структуры данных во время компиляции не требуется) .

Тип, выделенный кучей, также обеспечивает защиту (не всегда) от проблемы переполнения стека, поскольку память кучи значительно больше по размеру, чем память стека (обычно 1–8 МБ памяти стека) . Дополнительное пространство памяти достигается за счет скорости, выделение стека происходит намного быстрее, чем выделение кучи. Кроме того, есть несколько серьезных проблем с памятью, выделенной кучей, как описано ниже.

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

  • Утечки памяти: забудьте освободить память
  • Висячие указатели: слишком раннее освобождение памяти

В следующей статье мы углубимся в эти проблемы и более подробно обсудим возможные решения.

Спасибо за чтение.