Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Obektno-orientirovannoe_programmirovanie.doc
Скачиваний:
14
Добавлен:
19.08.2019
Размер:
271.36 Кб
Скачать

20. Механизмы управления памятью в c#

В C# для управления памятью используется сборщик мусора - механизм, который позволяет программисту не заботиться о ручном освобождении памяти. В .NET используется сборщик мусора, основанный на поколениях.

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

А что если попытаться отделить новые объекты (ведь именно среди них смертность так велика) от старых? Именно эта идея и привела к разработке сборщика мусора, основанного на поколениях.

GC .NET поддерживает три поколения 0, 1 и 2. Поколения 0 и 1 считаются эфемерными. Рождаясь, объекты попадаются в нулевое поколение. Большая их часть помирает, не дождавшись первой сборки мусора. Те из них, кто переживает первую в своей жизни сборку мусора, попадают в первое поколение. Первое поколение – это своего рода отстойник. Оно позволяет отфильтровать объекты, которые не успели умереть к моменту сборки мусора по чистой случайности. Второе поколение – это, можно сказать, дом престарелых. В нем доживают свой немалый век долгожители.

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

Сборка мусора во втором поколении происходит крайне редко. Именно сборка этого поколения является самой дорогой.

Поколения располагаются друг за другом. Сначала идет второе поколение. За ним первое, а за ним нулевое. С каждой сборкой мусора (если, конечно, не складывается ситуация, когда все объекты эфемерных поколений умерли) объекты младших поколений продвигаются в следующее (более старое) поколение. Это приводит к сдвижке указателей на начало поколения вперед и вперед.

Есть три причины, вызывающих запуск процесса сборки мусора:

1)При очередном выделении памяти GC замечает, что превышен размер нулевого поколения.

2)Приложение самостоятельно вызывает метод GC.Collect().

3)Нехватка памяти в ОС.

21. Наследование в c#

Следует различать 2 вида отношений: HAS-A (отношение «содержит») и IS-A (отношение «является»).

Отношение «содержит» - это композиция. Когда объект одного класса содержит один или более объектов других классов.

Отношение «является» - это наследование. В этом случае объект типа производного класса является так же объектом типа базового класса. Обратное не верно.

И наследование и композиция способствуют повторному использованию кодов путем создания новых классов, которые имеют новые черты с существующими классами.

В C# для нового класса может быть указанный баз. класс. Это делается в описании класса после его имени. Ставится : и указывается базовый класс.

public class First {…}

public class Second:First {…}

Не указывается тип наследования. В C# нет множественного наследования для классов. У одного производного класса Мб только 1 баз. класс, но 1 баз. класс может иметь несколько производных.

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

public class First

{ public First () {…}

public First (int a) {…} }

public class Second:First

{public Second {…}

public Second (int a) {…}}

Second s1 = new Second ();

Second s2 = new Second (2);

Если конструктор по умолчанию у базового класса отсутствует, то возникает ошибка времени компиляции. Можно явно указать, какой конструктор базового класса использовать. Для этого нужно в конструкторе производного класса после заголовка поставить : и записать ключ. слово base, которое заменяет имя конструктора базового класса.

public class First

{public First (int a) {…}}

public class Second:First

{public Second():base(7){…}

public Second(int a):base(a){…} }

В c++ была возможность записи списка инициализации, в C# - нет. Из конструктора класса кроме конструктора базового класса Мб вызван люб. другой конструктор данного класса. По синтаксису такой вызов аналогичен использованию base. Одновременное использование this и base недопустимо.

public class First

{public First(int a) {…}}

public class Second:First

{public Second():this(7) {…}

public Second(int a):base (a) {…}}