Ссылочные типы в C#

Сборщик мусора (GC) внутри CLR управляет всем, что касается размещения объектов. Он может перемещать объекты в любое время. При этом CLR обновляет переменные, ссылающиеся на эти объекты. Обычно вас не заботит точное местоположение объекта в куче, и вам не нужно беспокоиться о том, перемещен он или нет.

Но есть редкие случаи, например, при взаимодействии с “родными” DLL-библиотеками, когда может понадобиться получить прямой указатель памяти на объект в куче.

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

По соглашению термином объект обозначается экземпляр ссылочного типа, в то время как термином значение — экземпляр типа значений, но все экземпляры любого типа (ссылочного типа или типа значений) также унаследованы от типа object.

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

1
2
object 01 = new object ();
object 02 = 01;

Подобно исполняющей системе Java, среда CLR управляет всеми ссылками на объекты в куче. В С++ необходимо явно удалять объекты, расположенные в куче, причем в некоторый тщательно выбранный момент.

Но в управляемой среде CLR за вас это делает GC. Это избавляет от необходимости заботиться об удалении объектов из памяти и минимизирует утечки памяти. В любой момент времени GC может определить количество ссылок на определенный объект в куче. Если он выясняется, что ссылок нет, значит, можно начать процесс уничтожения объекта в куче.

Предыдущий фрагмент кода включает две ссылки на один и тот же объект. Первая из них, 01, инициализируется созданием нового экземпляра object, а вторая — 02 — инициализируется присваиванием первой, 01. GC не удалит этот объект из кучи до тех пор, пока обе ссылки не выйдут из их области видимости. Если бы метод возвращал копию ссылки тому, кто его вызывает, то GC продолжал бы отслеживать ссылку на данный объект, даже несмотря на то, что создавший его метод уже завершился.

Для тех, кто пришел из мира С++: фундаментальный способ трактовки объектов С++ в мире С# “вывернут наизнанку”. В С++ объекты размещаются в стеке, если только они не создаются явно с помощью операции new, которая возвращает указатель на объект в “родной” куче. В С# создавать объекты ссылочных типов в стеке нельзя.

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

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100