Глава.21 .Автоматическое.управление.памятью.(уборка.мусора)
переменной
pbytes
адрес объекта из начала блока
fixed
. При достижении конца
блока компилятор создает IL-инструкцию, возвращающую переменной
pbytes
значение
null
. Она перестает ссылаться на объект, позволяя удалить этот объект
в ходе следующей уборки мусора.
Флаги
Weak
и
WeakTrackResurrection
могут применяться как в сценари-
ях взаимодействия с неуправляемым кодом, так и при использовании только
управляемого кода. Флаг
Weak
указывает, что объект уже помечен как мусор,
но занимаемая им память пока может оказаться невостребованной. А вот флаг
WeakTrackResurrection
указывает на необходимость возвращения памяти. В то
время как флаг
Weak
применяется повсеместно, я еще ни разу не видел применения
флага
WeakTrackResurrection
в реальных приложениях.
Предположим, что объект
A
периодически вызывает метод для объекта
B
. Но на-
личие ссылки на объект
B
со стороны объекта
A
защищает его от уборщика мусора,
и вполне возможны ситуации, в которых такое поведение нежелательно. Предпо-
ложим, что вместо этого нам нужно, чтобы объект
A
вызывал метод объекта
B
при
условии, что последний находится в управляемой куче. Для решения этой задачи
объекту
A
следует вызвать метод
Alloc
класса
GCHandle
, передав этому методу ссыл-
ку на объект
B
и флаг
Weak
. В результате в объекте
A
будет храниться возвращенная
ссылка на экземпляр
GCHandle
, а не реальная ссылка на объект
B
.
При отсутствии других корней, сохраняющих объект
B
, теперь он может отправ-
ляться в мусорную корзину. Если объекту
A
понадобится вызвать метод объекта
B
, он
обратится к предназначенному только для чтения свойству
Target
класса
GCHandle
.
Возвращение этим свойством значения, отличного от
null
, указывает, что объект
B
еще существует. После этого код объекта
A
сможет привести возвращенную ссылку
к типу объекта
B
и вызвать метод. Если же свойство
Target
возвращает значение
null
, значит, объект
B
уничтожен уборщиком мусора, и объект
A
не будет пытаться
вызвать метод объекта
B
. Впрочем, код объекта
A
может вызвать метод
Free
типа
GCHandle
, чтобы разорвать связь с экземпляром
GCHandle
.
Поскольку из-за высоких требований к безопасности при фиксации или сохра-
нении объекта в памяти работать с типом
GCHandle
не просто, в пространство имен
System
был включен вспомогательный класс
WeakReference
:
public sealed class WeakReference : ISerializable where T : class {
public WeakReference(T target);
public WeakReference(T target, Boolean trackResurrection);
public void SetTarget(T target);
public Boolean TryGetTarget(out T target);
}
Это не более чем объектно-ориентированная обертка для экземпляра
GCHandle
: конструктор этого класса вызывает метод
Alloc
класса
GCHandle
,
его свойство
TryGetTarget
читает свойство
Target
класса
GCHandle
, метод
SetTarget
задает свойство
Target
класса
GCHandle
, а метод
Finalize
(выше не
показан, поскольку является защищенным) — метод
Free
класса
GCHandle
. Для
работы с классом
WeakReference
коду не требуется специального разрешения, так
603
Мониторинг.и.контроль.времени.жизни.объектов
как этот класс поддерживает только слабые ссылки; поведение, предоставляемое
экземплярами
GCHandle
, размещенными в режимах
Normal
или
Pinned
, не под-
держивается. Недостатком класса
WeakReference
является необходимость
пребывания объекта в куче. Из-за этого объекты
WeakReference
«весят» больше
экземпляров
GCHandle
.
Do'stlaringiz bilan baham: |