Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2213 / 889 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 10:

Управление памятью и сборка мусора

Аннотация: Управление памятью с точки зрения разработчика компилятора. Проблемы управления памятью. Статическое и динамическое размещение памяти. Стековый механизм управления памятью. Управление кучей. Подсчет ссылок и разметка памяти. Управление памятью в .NET.

Управление памятью с точки зрения разработчика компилятора

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

Итак, управление памятью при разработке компилятора является вопросом одновременно и машинно-зависимым, и языково-зависимым. В связи с этим разработчик компилятора должен найти наиболее эффективное отображение средств управления памятью, предлагаемых языком программирования, на заданную аппаратуру и ОС.

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

Основные фазы работы с памятью

Память - это один из самых важных ресурсов компьютера. Так как современные языки программирования не обязывают программиста работать напрямую с физическими ячейками памяти, на компилятор языка программирования возлагается ответственность за обеспечение доступа к физической памяти, ее распределение и утилизацию. В качестве ресурса могут выступать самые разные логические и физические единицы: обычные переменные примитивного типа, массивы, структуры, объекты, файлы и т.д. Со всеми этими объектами необходимо работать и, следовательно, обеспечить выделение памяти под связанные с ними переменные в программах.

Для этого компилятор должен последовательно выполнить следующие задачи:

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

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