Составители:
Рубрика:
ти. При этом размеры блоков в общем случае различны. Функции malloc
приходится выполнять поиск свободного блока нужного размера, разби-
вать этот блок и затем вносить необходимые изменения в список блоков.
Ясно, что выполнение этих действий требует значительно больше време-
ни, чем простое увеличение указателя HeapPtr.
1.4.2. Алгоритм сборки мусора
Перед тем как приступить к описанию алгоритма сборки мусора в
.NET, необходимо сделать важное замечание, касающееся уровня абстрак-
ции, на котором мы будем рассматривать этот вопрос. Дело в том, что нам
придется отрешиться от понятий, с которыми оперирует спецификация
CLI, потому что сборщик мусора относится не к спецификации, а к кон-
кретной реализации. Другими словами, мы не можем обсуждать сборщик
мусора в терминах виртуальной системы выполнения. Вместо этого нам
придется перейти на уровень конкретной системы выполнения, имеющей
следующие особенности:
• она исполняет не CIL-код, а порожденный JIT-компилятором
код процессора семейства Intel x86;
• для каждого потока выполнения существует стек, в котором рас-
положены фреймы вызванных методов. Каждый фрейм содер-
жит адрес возврата, адрес фрейма предыдущего метода в стеке, а
также локальные переменные и параметры метода;
• стеки вычислений в явном виде отсутствуют. Вместо них ис-
пользуются регистры процессора и стек потока;
• объектные ссылки представляют собой обычные указатели на
объекты в управляемой куче.
Ключевую роль в работе сборщика мусора играет понятие корень
(root). Корнем считается указатель на объект кучи, расположенный вне
кучи. Таким образом, корнями являются глобальные переменные, стати-
ческие поля классов, локальные переменные и параметры методов, а так-
же регистры процессора, содержащие указатели на объекты кучи.
Работа сборщика мусора основана на предположении, что объекты,
непосредственно или транзитивно достижимые из корней, нужно сохра-
нить в куче, так как они могут использоваться в программе. Все остальные
объекты можно удалить.
Запуск сборщика мусора осуществляется в тот момент, когда сово-
купный размер объектов в куче достигает некоторой границы. При этом
все потоки, запущенные приложением, приостанавливаются до заверше-
ния сборки мусора.
Для каждой точки в коде программы сборщик мусора может эффек-
тивно определить набор корней благодаря специальной таблице корней.
Эта таблица строится JIT-компилятором, и в ней каждому адресу в коде ка-
Введение в архитектуру Microsoft .NET Framework
29
Область локальных данных существует ровно столько, сколько ис-
полняется метод, состоянию которого она принадлежит. После прекраще-
ния работы метода она автоматически освобождается.
В верифицированном коде использование области локальных дан-
ных запрещено.
1.4. Автоматическое управление памятью
Одной из основных особенностей платформы .NET, делающих ее
привлекательной для разработки приложений, является механизм автома-
тического управления памятью, известный как сборка мусора (garbage col-
lection).
Спецификация CLI утверждает, что память для объектов, используе-
мых в программе, выделяется в управляемой куче (managed heap), которая
периодически очищается от ненужных объектов сборщиком мусора.
Принцип работы сборщика мусора в спецификации не определен, поэто-
му разработчики реализаций CLI могут использовать любые алгоритмы,
корректно выполняющие очистку управляемой кучи.
В .NET реализован так называемый сборщик мусора с поколениями
(generational garbage collector), работающий на основе построения графа
достижимости объектов.
1.4.1. Выделение памяти в управляемой куче
Под управляемую кучу резервируется непрерывная область адресно-
го пространства процесса. Система выполнения поддерживает специаль-
ный указатель (назовем его HeapPtr), содержащий адрес, по которому бу-
дет выделена память для следующего объекта. Когда куча не содержит ни
одного объекта, HeapPtr указывает на начало кучи. Выделение памяти для
объекта заключается в увеличении HeapPtr на количество байт, занимае-
мое этим объектом в куче.
Для некоторых объектов определены методы Finalize, выполняю-
щие некие действия при удалении объекта из кучи. Эти методы являются
аналогами деструкторов языка C++ и используются главным образом для
освобождения системных ресурсов, связанных с объектами. В целях повы-
шения эффективности сборщика мусора при выделении памяти для объе-
кта, имеющего метод Finalize, адрес этого объекта заносится в список за-
вершения (finalization list).
Если сравнить механизм выделения памяти в управляемой куче .NET
с работой функции malloc языка C, можно прийти к выводу, что функция
malloc работает гораздо менее эффективно. Причина в том, что исполня-
ющая среда языка C организует кучу в виде связного списка блоков памя-
28
CIL и системное программирование в Microsoft .NET
28 CIL и системное программирование в Microsoft .NET Введение в архитектуру Microsoft .NET Framework 29 Область локальных данных существует ровно столько, сколько ис- ти. При этом размеры блоков в общем случае различны. Функции malloc полняется метод, состоянию которого она принадлежит. После прекраще- приходится выполнять поиск свободного блока нужного размера, разби- ния работы метода она автоматически освобождается. вать этот блок и затем вносить необходимые изменения в список блоков. В верифицированном коде использование области локальных дан- Ясно, что выполнение этих действий требует значительно больше време- ных запрещено. ни, чем простое увеличение указателя HeapPtr. 1.4.2. Алгоритм сборки мусора 1.4. Автоматическое управление памятью Перед тем как приступить к описанию алгоритма сборки мусора в .NET, необходимо сделать важное замечание, касающееся уровня абстрак- Одной из основных особенностей платформы .NET, делающих ее ции, на котором мы будем рассматривать этот вопрос. Дело в том, что нам привлекательной для разработки приложений, является механизм автома- придется отрешиться от понятий, с которыми оперирует спецификация тического управления памятью, известный как сборка мусора (garbage col- CLI, потому что сборщик мусора относится не к спецификации, а к кон- lection). кретной реализации. Другими словами, мы не можем обсуждать сборщик Спецификация CLI утверждает, что память для объектов, используе- мусора в терминах виртуальной системы выполнения. Вместо этого нам мых в программе, выделяется в управляемой куче (managed heap), которая придется перейти на уровень конкретной системы выполнения, имеющей периодически очищается от ненужных объектов сборщиком мусора. следующие особенности: Принцип работы сборщика мусора в спецификации не определен, поэто- • она исполняет не CIL-код, а порожденный JIT-компилятором му разработчики реализаций CLI могут использовать любые алгоритмы, код процессора семейства Intel x86; корректно выполняющие очистку управляемой кучи. • для каждого потока выполнения существует стек, в котором рас- В .NET реализован так называемый сборщик мусора с поколениями положены фреймы вызванных методов. Каждый фрейм содер- (generational garbage collector), работающий на основе построения графа жит адрес возврата, адрес фрейма предыдущего метода в стеке, а достижимости объектов. также локальные переменные и параметры метода; • стеки вычислений в явном виде отсутствуют. Вместо них ис- 1.4.1. Выделение памяти в управляемой куче пользуются регистры процессора и стек потока; Под управляемую кучу резервируется непрерывная область адресно- • объектные ссылки представляют собой обычные указатели на го пространства процесса. Система выполнения поддерживает специаль- объекты в управляемой куче. ный указатель (назовем его HeapPtr), содержащий адрес, по которому бу- Ключевую роль в работе сборщика мусора играет понятие корень дет выделена память для следующего объекта. Когда куча не содержит ни (root). Корнем считается указатель на объект кучи, расположенный вне одного объекта, HeapPtr указывает на начало кучи. Выделение памяти для кучи. Таким образом, корнями являются глобальные переменные, стати- объекта заключается в увеличении HeapPtr на количество байт, занимае- ческие поля классов, локальные переменные и параметры методов, а так- мое этим объектом в куче. же регистры процессора, содержащие указатели на объекты кучи. Для некоторых объектов определены методы Finalize, выполняю- Работа сборщика мусора основана на предположении, что объекты, щие некие действия при удалении объекта из кучи. Эти методы являются непосредственно или транзитивно достижимые из корней, нужно сохра- аналогами деструкторов языка C++ и используются главным образом для нить в куче, так как они могут использоваться в программе. Все остальные освобождения системных ресурсов, связанных с объектами. В целях повы- объекты можно удалить. шения эффективности сборщика мусора при выделении памяти для объе- Запуск сборщика мусора осуществляется в тот момент, когда сово- кта, имеющего метод Finalize, адрес этого объекта заносится в список за- купный размер объектов в куче достигает некоторой границы. При этом вершения (finalization list). все потоки, запущенные приложением, приостанавливаются до заверше- Если сравнить механизм выделения памяти в управляемой куче .NET ния сборки мусора. с работой функции malloc языка C, можно прийти к выводу, что функция Для каждой точки в коде программы сборщик мусора может эффек- malloc работает гораздо менее эффективно. Причина в том, что исполня- тивно определить набор корней благодаря специальной таблице корней. ющая среда языка C организует кучу в виде связного списка блоков памя- Эта таблица строится JIT-компилятором, и в ней каждому адресу в коде ка-
Страницы
- « первая
- ‹ предыдущая
- …
- 19
- 20
- 21
- 22
- 23
- …
- следующая ›
- последняя »