В примере Serialize (Сериализация) второй экземпляр объекта Customer (Клиент) был присвоен той же переменной, которой раньше был присвоен первый экземпляр. При этом для удаления первого экземпляра класса из памяти деструктор не вызывался. В данном примере ни одна из выделенных областей памяти никогда не освобождалась. Для освобождения памяти от объектов, которые являются экземплярами классов, объявленных с помощью ключевого слова _дс (сборщик мусора), платформа .NET использует автоматическую сборку мусора. Если память, выделенная в управляемой динамически распределяемой области памяти, становится висячей или выходит из области видимости, то она заносится в список участков памяти, подлежащих освобождению. Периодически система инициирует процесс сборки мусора. Освободившаяся в результате этого память возвращается в динамически распределяемую область памяти.
Благодаря автоматическому управлению памятью утечка памяти в системе исключается. Утечка памяти является одной из самых распространенных ошибок при программировании на языках С и C++. В большинстве случаев за счет использования автоматической сборки мусора распределение памяти в динамически распределяемой области памяти происходит значительно быстрее по сравнению с классическими схемами. Обратите внимание, что такие переменные KaKpcust и plist являются управляемыми указателями на объекты, а не самостоятельными объектами. Именно вследствие этого и возможна сборка мусора.
Сборка мусора — одна из нескольких служб, предоставляемых общеязыковой средой выполнения CLR программам, выполняющимся на платформе .NET [Формально метаданные, общая система типов CTS (Common Type System), спецификация общего языка CLS и виртуальная система выполнения (Virtual Execution System— VES) также являются частью общеязыковой среды выполнения CLR. Прилагательное "общеязыковая" означает, что среда выполнения является общей для всех языков. Система виртуального выполнения VES загружает и выполняет .NET-программы и поддерживает динамическое связывание. Обратитесь к документам, описывающим общеязыковую инфраструктуру (Common Language Infrastructure — CLI), а именно, к разделу "Partition I: Concepts and Architecture", посвященному концепциям и архитектуре. Эти документы переданы для дальнейшего рассмотрения Европейской Ассоциации производителей ЭВМ (European Computer Manufacturers' Association — ЕСМА). Упомянутые документы загружаются вместе с набором инструментальных средств разработки программного обеспечения .NET Framework SDK.].
Данные, участвующие в процессе сборки мусора, инициируемом общеязыковой средой выполнения CLR, называются управляемыми данными. Управляемый код— это код, который способен использовать службы, предоставляемые общеязыковой средой выполнения CLR. .NET-компиляторы, которые генерируют код на языке MSIL, могут генерировать управляемый код.
Управляемый код не удовлетворяет требованиям типовой безопасности автоматически. Язык C++ может послужить тому классическим примером. Чтобы класс участвовал в сборке мусора (т.е. был управляемым), при его объявлении следует использовать атрибут _дс (сборщик мусора). Компилятор для C++ запрещает в таких классах использовать арифметические операции над указателями. Тем не менее, код на C++ не может быть надежно проверен на типовую безопасность, поскольку используются библиотеки на С и C++.
Проверка кода на типовую безопасность происходит перед его компиляцией. Такая проверка является необязательной и может быть пропущена, если код аттестован. Одно из самых существенных отличий проверяемого кода от непроверяемого состоит в том, что в проверяемом коде не могут использоваться указатели. Код, в котором используются указатели, может разрушить общую систему типов CTS и в результате его трансляции может получиться код, не удовлетворяющий типовой безопасности.
Код, который удовлетворяет типовой безопасности, не может быть легко разрушен. Например, перезапись буфера не может повредить другие структуры данных или программы. К коду, удовлетворяющему требованиям типовой безопасности, можно применить политику безопасности [Более подробно этот вопрос обсуждается в главе 13 "Зашита".]. Например, можно разрешить или запретить доступ к некоторым файлам, или элементам пользовательского интерфейса. Вы можете предотвратить выполнение кода, полученного из неизвестных вам источников. Чтобы предотвратить разрушение системы безопасности платформы .NET, вы можете запретить доступ к неуправляемому коду. Благодаря типовой безопасности можно также изолировать выполняемые ветви кода .NET друг от друга [Области приложений (Application Domains) обсуждаются в главе 8 "Классы каркаса .NET Framework".].