Обратите внимание, что ссылка на объект Car(myCar)
MakeACar и не передавалась за пределы определяющей области видимости (через возвращаемое значение или параметр ref/out). Таким образом, после завершения данного метода ссылка myCar оказывается недостижимой, и объект Car теперь является кандидатом на удаление сборщиком мусора. Тем не менее, важно понимать, что восстановление занимаемой этим объектом памяти немедленно после завершения метода MakeACar гарантировать нельзя. В данный момент можно предполагать лишь то, что когда исполняющая среда инициирует следующую сборку мусора, объект myCar может быть безопасно уничтожен.Как вы наверняка сочтете, программирование в среде со сборкой мусора значительно облегчает разработку приложений. И напротив, программистам на языке C++ хорошо известно, что если они не позаботятся о ручном удалении размещенных в куче объектов, тогда утечки памяти не заставят себя долго ждать. На самом деле отслеживание утечек памяти — один из требующих самых больших затрат времени (и утомительных) аспектов программирования в неуправляемых средах. За счет того, что сборщику мусора разрешено взять на себя заботу об уничтожении объектов, обязанности по управлению памятью перекладываются с программистов на исполняющую среду.
Код CIL для ключевого слова new
Когда компилятор C# сталкивается с ключевым словом new, он вставляет в реализацию метода инструкцию newobj
ildasm.ехе, то найдете внутри метода MakeACar следующие операторы CIL:.method assembly hidebysig static
void '<
{
// Code size 8 (0x8)
.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: ret
} // end of method '
Прежде чем ознакомиться с точными правилами, которые определяют момент, когда объект должен удаляться из управляемой кучи, давайте более подробно рассмотрим роль инструкции newobj
Для содействия его усилиям в управляемой куче поддерживается указатель (обычно называемый
newobj заставляет исполняющую среду выполнить перечисленные ниже основные операции.1. Подсчитать общий объем памяти, требуемой для размещения объекта (в том числе память, необходимую для членов данных и базовых классов).
2. Выяснить, действительно ли в управляемой куче имеется достаточно пространства для сохранения размещаемого объекта. Если места хватает, то указанный конструктор вызывается, и вызывающий код в конечном итоге получает ссылку на новый объект в памяти, адрес которого совпадает с последней позицией указателя на следующий объект.
3. Наконец, перед возвращением ссылки вызывающему коду переместить указатель на следующий объект, чтобы он указывал на следующую доступную область в управляемой куче.
Описанный процесс проиллюстрирован на рис. 9.2.
В результате интенсивного размещения объектов приложением пространство внутри управляемой кучи может со временем заполниться. Если при обработке инструкции newobj
Правило.
Если в управляемой куче не хватает пространства для размещения требуемого объекта, то произойдет сборка мусора.Однако то, как конкретно происходит сборка мусора, зависит от типа сборки мусора, используемого приложением. Различия будут описаны далее в главе.
Установка объектных ссылок в null
Программисты на C/C++ часто устанавливают переменные указателей в null
null ссылок на объекты в С#. В качестве примера измените метод MakeACar следующим образом:static void MakeACar
{
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT