- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
• Правило. Если управляемая динамическая память недостаточна дли размещения очередного объекта, выполняется сборка мусора.
В процессе сборки мусора сборщик мусора временно приостанавливает все активные потоки в рамках текущего процесса, чтобы гарантировать, что приложение не получит доступа к динамической памяти в процессе сборки мусора. Тему потоков мы рассмотрим в главе 14, а пока что воспринимайте поток, как "нить" выполнения в пределах выполняющейся программы. После завершения цикла сборки мусора приостановленным потокам будет разрешено продолжить работу. К счастью, сборщик мусора .NET хорошо оптимизирован, и вы вряд ли заметите соответствующие короткие перерывы в работе вашего приложения.
Роль корней приложения
Теперь мы вернемся к вопросу о том, как сборщик мусора определяет, когда объект "больше не нужен". Чтобы понять это, необходимо рассмотреть понятие корней приложения. Упрощенно говоря, корень- это место в памяти со ссылкой на объект, размещенный в динамической памяти. Строго говоря, корень может относиться к любой из следующих категорий.
• Ссылки на глобальные объекты (хотя они и не позволены в C#, программный код CIL допускает размещение глобальных объектов).
• Ссылки на используемый в настоящий момент статические объекты и поля.
• Ссылки на локальные объекты в пределах данного метода.
• Ссылки на объектные параметры, предаваемые методу.
• Ссылки на объекты, ожидающие финализации (соответствующее понятие будет описано в этой главе позже).
• Любые регистры процессора, ссылающиеся на локальный объект.
В процессе сборки мусора среда выполнения проверяет объекты в управляемой динамической памяти и определяет, остаются ли они доступными для приложения (иначе говоря, укорененными). Для этого среда CLR строит объектный граф, изображающий каждый объект в динамической памяти, достижимый для приложения. Объектные графы будут рассматриваться подробнее при обсуждении сериализации объектов (см. главу 17). На данный момент вам достаточно знать, что объектные графы используются для учета всех достижимых объектов. Следует знать и о том, что сборщик мусора никогда не учитывает один и тот же объект дважды, вследствие чего, в отличие от классического подхода COM. здесь не возникает опасности циклического учета ссылок,.
Предположим, что управляемая динамическая память содержит множество объектов, имена которых A, B, C, D, E, F и G. В процессе сборки мусора эти объекты (а также все внутренние объектные ссылки, которые эти объекты могут содержать) проверяются на наличие у них активных корней, После построения графа недостижимые объекты (мы будем предполагать, что это объекты C и F) обозначаются, как мусор.
На рис. 5.3 представлен возможный объектный граф для только что описанного сценария (направленные стрелки, связывающие объекты в таком графе, можно заменить словами "зависит от" или "требует", – например, "E зависит от G и косвенно от B", "A не зависит ни от чего" и т.д.).
Рис. 5.3. Объектные графы строятся для выявления объектов, достижимых из корней приложения
Если объекты помечены для уничтожения (в данном случае это C и F – они не включены в объектный граф), эти объекты удаляются из памяти. В этот момент оставшееся пространство в динамической памяти уплотняется, что в свою очередь заставляет среду CLR модифицировать множество корней активного приложения, чтобы они обеспечивали правильные ссылки на точки размещения в памяти (это делается автоматически и незаметно). Наконец, соответствующим образом изменяется указатель на следующий объект. На рис. 5.4 показан результат преобразований.
Рис. 5.4. "Чистая и компактная" динамическая память
Замечание. Строго говоря, сборщик мусора использует два разных фрагмента динамической памяти, один из которых предназначен специально для хранения очень больших объектов. К этой динамической памяти при сборке мусора система обращается реже, поскольку при размещении больших объектов возможные потери производительности выше. Тем не менее, вполне допустимо считать "управляемую динамическую память" единым регионом в памяти.
Генерации объектов
Когда среда CLR пытается найти недоступные объекты, это не значит, что будет рассмотрен буквально каждый объект, размещенный в управляемой динамической памяти. Очевидно, что это требовало бы слишком много времени, особенно в реальных (т.е. больших) приложениях.
Чтобы оптимизировать процесс, каждый объект в динамической памяти приписывается определенной "генерации". Идея достаточно проста: чем дольше объект существует в динамической памяти, тем более вероятно то, что он должен там и оставаться. Например, объект, реализующий Main() будет находиться в памяти до тех пор, пока программа не закончится. С другой стороны, объекты, которые недавно размещены в динамической памяти, вероятнее всего, станут вскоре недостижимыми (например, объекты, созданные в рамках области видимости метода). При этих предположениях каждый объект в динамической памяти можно отнести к одной из следующих категорий.
• Генерация 0. Новые, только что размещенные объекты, которые еще никогда же предназначались для использования в процессе сборки мусора.
• Генерация 1. Объекты, которые "пережили" одну сборку мусора (т.е. были обозначены для использования в процессе сборки мусора, но не были удалены по той причине, что в динамической памяти оказалось достаточно места).
• Генерация 2. Объекты, ''пережившие" несколько сборок мусора.
Сборщик мусора сначала рассматривает объекты генерации 0. Если в результате выявления ненужных объектов и соответствующей чистки свободной памяти оказывается достаточно, все оставшиеся объекты относятся к генерации 1. Чтобы понять, как генерации объектов влияют на процесс сборки мусора, рассмотрите рис. 5.5. где схематически показано, как некоторое множество "выживших" объектов (A, B и E) генерации 0 переводятся в следующую генерацию после обновления остальной части памяти.
Рис 5.5. Объекты генерации 0, которые "пережили" сборку мусора, переходят к генерации 1
Если все объекты генерации 0 уже рассмотрены, но памяти все равно еще не достаточно, то рассматривается "достижимость" объектов генерации 1 и выполняется сборка мусора среди этих объектов. "Выжившие" объекты генерации 1 переходят к генерации 2. Если сборщик мусора все еще требует дополнительной памяти, тогда оцениваются объекты генерации 2. Здесь, если объект генерации 2 "выживает" в процессе сборки мусора, то такой объект сохраняет принадлежность к генерации 2, поскольку это предел для генераций объектов.
Итак, с помощью назначения признака генерации объектам в динамической памяти более новые объекты (например, локальные переменные) будут удаляться быстрее, тогда как старые объекты (такие как, например, объект приложения программы) будут "беспокоиться" значительно реже.
Тип System.GC
Библиотеки базовых классов предлагают тип класса System.GC, который позволяет программно взаимодействовать со сборщиком мусора, используя множество статических членов указанного класса. Следует заметить, что непосредственно использовать этот тип в программном коде приходится очень редко (если приходится вообще). Чаще всего члены типа System.GC используется тогда, когда создаются типы, использующие неуправляемые ресурсы. В табл. 5.1 предлагаются описания некоторых членов этого класса (подробности можно найти в документации .NET Framework 2.0 SDK).
Таблица 5.1. "Избранные" члены типа System.GC
Члены System.GC Описание AddMemoryPressure(), RemoveMemoryPressure() Позволяют указать числовое значение, характеризующее "срочность" вызова процесса сборки мусора. Эти методы должны изменять уровень "давления" согласованно (в частности, удаляемая величина не должна превышать добавленную) Collect() Вынуждает GC выполнить сборку мусора CollectionCount() Возвращает числовое значение, указывающее, сколько раз "выживала" данная генерация при сборке мусора GetGeneration() Возвращает информацию о генерации, к которой в настоящий момент относится объект GetTotalMemory() Возвращает оценку объема памяти (в байтах), выделенной для управляемой динамической памяти в настоящий момент. Логический параметр указывает, должен ли вызов ждать начала сборки мусора, чтобы возвратить результат MaxGeneration Возвращает максимум для числа генераций, поддерживаемых в системе. В Microsoft .NET 2.0, предполагается существование трех генераций (0, 1 и 2) SuppressFinalize() Устанавливает индикатор того, что данный объект не должен вызывать свой метод Finalize() WaitForPendingFinalizers() Приостанавливает выполнение текущего потока, пока не будут отработаны все объекты, предусматривающие финализацию. Этот метод обычно вызывается непосредственно после вызова GC.Collect()Рассмотрите следующий метод Main(), в котором иллюстрируется использование указанных членов System.GC.