} // end of method '
Прежде чем ознакомиться с точными правилами, которые определяют момент, когда объект должен удаляться из управляемой кучи, давайте более подробно рассмотрим роль инструкции newobj
Для содействия его усилиям в управляемой куче поддерживается указатель (обычно называемый
newobj заставляет исполняющую среду выполнить перечисленные ниже основные операции.1. Подсчитать общий объем памяти, требуемой для размещения объекта (в том числе память, необходимую для членов данных и базовых классов).
2. Выяснить, действительно ли в управляемой куче имеется достаточно пространства для сохранения размещаемого объекта. Если места хватает, то указанный конструктор вызывается, и вызывающий код в конечном итоге получает ссылку на новый объект в памяти, адрес которого совпадает с последней позицией указателя на следующий объект.
3. Наконец, перед возвращением ссылки вызывающему коду переместить указатель на следующий объект, чтобы он указывал на следующую доступную область в управляемой куче.
Описанный процесс проиллюстрирован на рис. 9.2.
В результате интенсивного размещения объектов приложением пространство внутри управляемой кучи может со временем заполниться. Если при обработке инструкции newobj
Правило.
Если в управляемой куче не хватает пространства для размещения требуемого объекта, то произойдет сборка мусора.Однако то, как конкретно происходит сборка мусора, зависит от типа сборки мусора, используемого приложением. Различия будут описаны далее в главе.
Установка объектных ссылок в null
Программисты на C/C++ часто устанавливают переменные указателей в null
null ссылок на объекты в С#. В качестве примера измените метод MakeACar() следующим образом:static void MakeACar()
{
Car myCar = new Car();
myCar = null;
}
Когда ссылке на объект присваивается null
myCar в данном примере) больше не указывает на какой-либо объект. Если теперь снова с помощью утилиты ildasm.exe просмотреть код CIL модифицированного метода MakeACar(), то можно обнаружить в нем код операции ldnull (заталкивает значение null в виртуальный стек выполнения), за которым следует код операции stloc.0 (устанавливает для переменной ссылку null):.method assembly hidebysig static
void '<
{
// Code size 10 (0xa)
.maxstack 1
.locals init (class SimpleGC.Car V_0)
IL_0000: nop
IL_0001: newobj instance void SimpleGC.Car::.ctor()
IL_0006: stloc.0
IL_0007: ldnull
IL_0008: stloc.0
IL_0009: ret
} // end of method '
Тем не менее, вы должны понимать, что присваивание ссылке значения null
Выяснение, нужен ли объект
Теперь вернемся к вопросу о том, как сборщик мусора определяет момент, когда объект больше не нужен. Для выяснения, активен ли объект, сборщик мусора использует следующую информацию.
• Корневые элементы в стеке: переменные в стеке, предоставляемые компилятором и средством прохода по стеку.
• Дескрипторы сборки мусора: дескрипторы, указывающие на объекты, на которые можно ссылаться из кода или исполняющей среды.