- •С# и объектно-ориентированное программирование. Содержание
- •Разбор простой программы на с#.
- •Варианты метода Main ()
- •Формальное определение класса в с#
- •2.1Ссылки на самого себя
- •Построение цепочки вызовов конструкторов с использованием this.
- •Модификаторы доступа с#
- •Инкапсуляция с использованием свойств .Net
- •Средства инкапсуляции с#
- •Инкапсуляция с использованием традиционных методов доступа и изменения
- •Свойства, доступные только для чтения и только для записи
- •Статические свойства
- •Статические конструкторы
- •Наследование в с#
- •Работа с конструктором базового класса
- •Множественное наследование.
- •Ключевое слово sealed
- •Поддержка полиморфизма в с#
- •Ключевые слова virtual и override
- •Абстрактные классы
- •Полиморфный интерфейс
- •Сокрытие методов
- •Правила приведения к базовому и производному классу
- •Ключевое слово as
- •Ключевое слово is
- •Применение модели включения – делегирования.
- •Определение вложенных типов
- •Обработка исключений
- •Роль обработки исключений в .Net
- •Составляющие процесса обработки исключений в .Net
- •Генерация общего исключения
- •Перехват исключений
- •Создание специальных исключений, способ первый
- •Обработка нескольких исключений.
- •Блок finally
- •Замечания по работе с исключениями
- •Время жизни объектов
- •Базовые сведения о времени жизни объектов
- •Роль корневых элементов приложения
- •Поколения объектов
- •Параллельная сборка мусора в версиях .Net 1.0 - .Net 3.5
- •Фоновая сборка мусора в версии .Net 4.0
- •Создание финализируемых объектов
- •Описание процесса финализации
- •Создание высвобождаемых объектов
- •Повторное использование ключевого слова using в с#
- •Взаимодействие со сборщиком мусора
- •Принудительная активизация сборки мусора
- •Создание финализируемых и высвобождаемых типов
- •Формализованный шаблон очистки
Принудительная активизация сборки мусора
Сборщик мусора .NET предназначен в основном для того, чтобы управлятьпамятью вместо разработчиков. Однако в очень редких случаях требуется принудительно запустить сборку мусора с помощью метода GC.Collect().
Примеры таких ситуацийприведены ниже.
Приложение приступает к выполнению блока кода, прерывание которого возможным процессом сборки мусора является недопустимым.
Приложение только что закончило размещать чрезвычайно большое количество объектов и нуждается в как можно скорейшем освобождении большого объема памяти.
Если выяснилось, что выполнение сборщиком мусора проверки на предмет наличия недостижимых объектов может быть выгодным, можно инициировать процесс сборки мусора явным образом, как показано ниже:
static void Main(string [ ] args)
{
// Принудительная активизация процесса сборки мусора и
// ожидание завершения финализации каждого из объектов.
GC.Collect ();
GC.WaitForPendingFinalizers ();
}
static void Main(string [ ] args)
{
// Принудительная активизация процесса сборки мусора и
// ожидание завершения финализации каждого из объектов.
GC.Collect ();
GC.WaitForPendingFinalizers ();
}
В случае принудительной активизации сборки мусора не забывайте вызвать метод GC.WaitForPendingFinalizers(). Это дает возможность всем финализируемым объектам произвести любую необходимую очистку перед продолжением работы программы. Метод GC.WaitForPendingFinalizers() незаметно приостанавливает выполнение вызывающего "потока" во время процесса сборки мусора, что очень хорошо, поскольку исключает вероятность вызова в коде каких-либо методов на объекте, который в текущий момент уничтожается.
Методу GC.Collect() можно передать числовое значение, отражающее старейшее поколение объектов, в отношении которого должен проводиться процесс сборки мусора. Например, чтобы CLR-среда анализировала только объекты поколения 0, необходимо использовать следующий код:
static void Main(string [ ] args)
{
// Исследование только объектов поколения 0
GC.Collect(0);
GC.WaitForPendingFinalizers();
}
Вдобавок методу Collect() во втором параметре может передаваться значение перечисления GCCollectionMode, которое позволяет более точно указать, каким образом исполняющая среда должна принудительно инициировать сборку мусора. Ниже показаны значения, доступные в этом перечислении:
public enum GCCollectionMode
{
Default, // Текущим значением по умолчанию является Forced.
Forced, // Указывает исполняющей среде начать сборку мусора немедленно1
Optimized // Позволяет исполняющей среде выяснить, оптимален
//ли настоящий момент для удаления объектов.
}
Как и при любой сборке мусора, в случае вызова GC.Collect() уцелевшим объектам назначается статус объектов более высокого поколения. Чтобы удостовериться в этом, модифицируем метод Main() следующим образом:
static void Main(string[] args)
{
// Отображение примерного количества байтов в куче.
Console.WriteLine("Estimated bytes on heap: {0}",
GC.GetTotalMemory(false));
// Отсчет значения MaxGeneration начинается с нуля.
Console.WriteLine("This OS has {0} object generations.\n",
(GC.MaxGeneration + 1) ) ;
Car refToMyCar = new Car("Zippy", 100);
Console.WriteLine(refToMyCar.ToString());
// Вывод информации о поколении, к которому
// относится refToMyCar.
Console.WriteLine ("\nGeneration of refToMyCar is: {0}",
GC.GetGeneration(refToMyCar));
// Создание большого количества объектов для целей тестирования.
object[] tonsOfObjects = new object[50000];
for (int i = 0; i < 50000; i++)
tonsOfObjects [i] = new object ();
// Выполнение сборки мусора в отношении только
// объектов, относящихся к поколению 0.
GC.Collect @, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// Вывод информации о поколении, к которому
// относится refToMyCar.
Console.WriteLine("\nGeneration of refToMyCar is: {0}",
GC.GetGeneration(refToMyCar));
// Выполнение проверки, удалось ли
// tonsOfObjects[9000] уцелеть после сборки мусора.
if (tonsOfObjects[9000] !=null)
{
// Вывод поколения tonsOfObjects [ 9000]
Console.WriteLine("Generation of tonsOfObjects[9000] is: {0}",
GC.GetGeneration(tonsOfObjects [ 9000]));
}
else
// tonsOfObjects[9000] больше не существует.
Console.WriteLine("tonsOfObjects[9000] is no longer alive.");
// Вывод информации о том, сколько раз в отношении
// объектов каждого поколения выполнялась сборка мусора.
Console.WriteLine("\nGen 0 has been swept {0} times",
GC.CollectionCount@));
Console.WriteLine("Gen 1 has been swept {0} times",
GC.CollectionCountA));
Console.WriteLine("Gen 2 has been swept {0} times",
GC.CollectionCountB));
Console.ReadLine();
}
Дя целей тестирования был создан очень большой массив типа object (состоящий из 50000 элементов). Как можно увидеть по приведенному ниже выводу, хотя в данном методе Main() и был сделан только один явный запрос на выполнение сборки мусора (с помощью метода GC.Collect()), среда CLR в фоновом режиме провела несколько таких сборок.
Результаты работы программы (вывод на консоль):
Estimated bytes on heap: 70240
This OS has 3 object generations.
Zippy is going 100 MPH
Generation of refToMyCar is: 0
Generation of refToMyCar is: 1
Generation of tonsOfObjects [ 9000] is: 1
Gen 0 has been swept 1 times
Gen 1 has been swept 0 times
Gen 2 has been swept 0 times
