Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Медведев_С++_CLI_C#_Java_J#.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
5 Мб
Скачать
☆

3.4Сборщик мусора

Сборщик мусора GC (garbage collector) предназначен для управления распределением памяти внутри управляемой кучи. Сборщику мусора известно размещение управляемых данных в куче. Каждый новый управляемый объект помещается в свободном пространстве кучи, и адрес объекта присваивается соответствующему управляемому указателю (managed pointer). Если свободного пространства будет недостаточно, то сборщик мусора удалит уже неиспользуемые данные, уплотнив кучу. При этом будут изменены ссылки в управляемых указателях на перемещённые данные. Сборщик мусора оперирует только с управляемыми типами (managed types). Иногда сборщик мусора может переслать данные из кучи в стек, если данные невелики и имеют малое время жизни. При этом перемещённые данные изменяют свой управляемый тип на тип-значение (value type). Следя за управляемыми указателями и данными, сборщик мусора способствует безопасности программы. Он по мере надобности уплотняет управляемую кучу, не допуская её переполнения, которое возможно было бы в неуправляемой куче по вине программиста.

3.5Ссылочные типы и типы-значения

C# и J#. В языке C# типы-значения размещаются в стеке, а управляемые данные, созданные посредством оператора new, в управляемой куче. Сам компилятор соотносит данные программы к тому или иному типу. Переменные, ссылаемые к управляемым данным, имеют ссылочный тип. Остальные переменные имеют тип-значение.

С++. В языке С++ нет управляемых типов. Компилятор помещает данные, созданные оператором new, в неуправляемой куче. Остальные данные программы помещаются в стеке. К данным кучи осуществляется ссылка с помощью указателей.

C++/CLI. В языке C++/CLI, являющемся расширением языка С++, программист по своему желанию может отнести данные как к неуправляемым типам, так и к управляемым различным типам, используя ключевые слова gcnew, delegate, event, property или ключевые слова с пробелами enum class, enum struct, interface class, ref class, ref struct, value class, value struct. В соответствии с его пожеланиями компилятор создаст их надлежащим образом. Данные, не помеченные ключевыми словами, считаются неуправляемыми данными, то есть данными языка С++.

В языке C++/CLI неуправляемые указатели, указывающие на неуправляемые данные, размещённые в неуправляемой куче, помечаются символом "*", а управляемые указатели, ссылающиеся на управляемые данные в управляемой куче, помечаются символом "^". В дальнейшем мы неуправляемые указатели будут называть указателями, а управляемые указатели будем называть дескрипторами. В отличие от указателей, жестко привязанных к конкретным областям неуправляемой кучи, значения дескрипторов могут меняться. Сборщик мусора, удаляя непотребные данные из управляемой кучи, меняет значения дескрипторов и уплотняет при этом кучу.

Итак, если нам необходимы объекты, размещаемые в управляемой куче, то необходимо при описании класса этих объектов применить пару слов ref class, а при создании объектов применить оператор gcnew и дескриптор, помеченный символом " Л ". Управляемые классы могут включать любые управляемые данные. Ссылки к управляемым данным (объектам) осуществляются только с помощью дескрипторов. При копировании управляемых данных (ссылочных данных), само данное в управляемой куче не перемещается, а создаётся новый дескриптор (ссылка) на него.

Данные типа значения размещаются в стеке, При копировании эти данные копируются в новую область стека. Обычно данные типа значения не громоздки, поскольку они размещены не в куче, а в программе, и поэтому увеличивают размер программы. В качестве значений представляют наиболее часто используемые данные, поскольку работа со стеком быстрее, чем с кучей. В качестве таких данных представлены все базовые данные типа int, char, bool, double, float и др. При желании эти данные могут быть размещены и в куче путем применения специальных классов-оболочек, например для размещения в куче символа типа char применяется специальный класс-оболочка Char. Язык C++/CLI содержит ключевые слова с пробелами value class и value struct для представления данных типа значение.

В примере 3.5.1 показано создание объекта типа-значения CBalll в стеке и в неуправляемой куче С++, а объекта типа class CBall2 в управляемой куче.

Пример 3.5.1. Использование стека, неуправляемой и управляемой куч на языке C++/CLI.

// C++/CLI

value class CBall1 // Класс CBalll имеет тип-значение

{

private:

int x, y;

public:

void Set (int vX, int vY)

{x= vX; y= vY;}

void Show ( )

{

System::Console::WriteLine("x= "+ x.ToString()+"y= " + y.ToString ( ));

}

};

ref class CBall2 // Класс CBall2 имеет управляемый тип

{

private:

int x, y;

public:

void Set (int vX, int vY)

{x= vX; y= vY;}

void Show ( )

{

System::Console::WriteLine("x= "+x.ToString()+"y= "+y.ToString());

}

};

void F()

{

CBall1 ball; // Создать объект в стеке

ball.Set(1, 11);

ball.Show();

CBall1 *pBalll= new CBall1(); // Создать объект в неуправляемой куче

pBalll->Set(2, 22);

pBalll->Show();

CBall2 ^pBall2=gcnew CBall2 (); // Создать объект в управляемой куче

pBall2->Set (3, 33);

pBall2->Show();

}

Компилятор языка C++/CLI контролирует правильность использования ключевых слов, чем значительно облегчает освоение .NET технологии. Сочетание обработки данных в стеке и неуправляемой куче с обработкой данных в управляемой куче в пределах одного программного кода делает язык C++/CLI уникальным, позволяющим разработать эффективные программы.