Управление памятью в С++
Инициализация массива, элементы которого содержат количество дней в каждом месяце года. Управление выделением памяти в С++. Перегрузка операторов new и delete. Создание производного класса с подсчетом ссылок. Алгоритм сборки мусора на уровне поколений.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | учебное пособие |
Язык | русский |
Дата добавления | 13.09.2015 |
Размер файла | 56,8 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Пример 2.29 Выделение памяти под новые объекты
struct Pool {
static Pool* gCurrentPool; // Пул для выделения памяти
enum { block_size = 8096 }; // Выберите свой любимый размер
unsigned char* space; //Следующая выделяемая область
size_t remaining; // Количество оставшихся байт в блоке
Pool() : space((unsigned char*)calloc(block_size, `\0')),
remaining(block_size) {}
void* Allocate(size_t bytes)
{
if (bytes > block_size)
return ::operator new(bytes); // Слишком большой запрос
if (gCurrentPool == NULL || bytes ? remaining)
gCurrentPool = new Pool;
void* memory = space;
space += bytes;
remaining -= bytes;
return memory;
}
};
class Foo {
public:
void* operator new(size_t bytes)
{
if (Pool::fCurrentPool == NULL)
Pool::gCurrentPool = new Pool;
return Pool::gCurrentPool->Allocate(bytes);
}
void operator delete(void*) {}
};
Выделение занимает лишь несколько машинных тактов, а освобождение происходит мгновенно. Нужно обратить внимание, что для выделения блоков вместо операторной функции ::operator new используется функция calloc(). Большинство компиляторов С++ выделяет большой блок с помощью функции calloc() (или функции операционной системы), а затем управляет объектами в полученном блоке. Если использовать ::operator new для выделения блоков, это кончится двойными затратами и двойной фрагментацией, поскольку эти блоки будут существовать в стандартных блоках менеджера памяти. При рассмотренной стратегии лучше обойти ::operator new. Описанная стратегия также хорошо работает в программах с более продолжительным сроком жизни, которые изначально создают множество объектов некоторого класса, но удаляют их относительно редко. Если операторы new и delete перегружаются на уровне классов, то оптимизацию можно ограничить классами, обладающими указанным свойством. массив память оператор ссылка
Многие алгоритмы сборки мусора на уровне поколений выглядят как в примере 2.30:
Пример 2.30 Алгоритм сборки мусора на уровне поколений
void Eval(Structure s)
{
// Создать локальные объекты
Eval(s.SomePart()); // Произвести вычисления для подструктуры
// Удалить локальные объекты
}
Размещение локальных объектов в стеке может ускорить выделение и освобождение памяти, но этот вариант часто неэффективен. Альтернативный вариант в примере 2.31 -- создать пул, локальный для Eval(), и уничтожить его целиком при выходе из Eval(). В области действия Eval() все временные объекты размещаются в этом пуле.
Пример 2.31 Ускорение выделения и освобождения памяти
void* operator new(size_t size, Pool* p)
{
return p->Allocate(size);
}
template <class Type>
class PoolP { // Указатель, использующий пул
private:
Type* pointee;
public:
PoolP(Pool* p) : pointee(new(p) Type) {}
~PoolP { pointee->Type::~Type(); }
// Все остальное для ведущих указателей
};
void Eval(Structure s)
{
Pool p; // Объявляется в стеке
PoolP<Foo> foo(&p); // Использует пул
Eval(s.SomePart()); // Использует свой собственный пул
f(p, s); // Вместо f(s); f будет использовать тот же пул
// Деструктор p уничтожает все сразу
}
2.6 Списки свободных блоков
Упрощенный список свободных блоков может использоваться только для объектов постоянного размера. Например, он не будет нормально работать с производными классами, в которых добавляются новые переменные, поскольку они будут иметь другой размер. Сам список тоже ограничивался одним размером; для передачи оператору delete правильного размера требовались виртуальные деструкторы.
Одно из несложных усовершенствований заключается в том, чтобы хранить в каждом узле списка не только адрес следующего указателя в списке, но и размер блока. Это позволит хранить в одном списке блоки разных размеров. При выделении памяти просматривается список, пока не находится блок, размеры которого достаточны для требуемых целей. Для этого придется хранить скрытую информацию о размере блока даже после его выделения, чтобы при уничтожении объекта восстанавливать весь блок. Стратегия подходит для очень маленьких списков, поскольку время поиска возрастает линейно с размером списка.
Более эффективное представление -- коллекция списков свободной памяти, в которой каждый список представляет блоки определенного размера. В примере 2.32, показана упрощенная, но полезная реализация.
Пример 2.32 Коллекция списков свободной памяти
class MemManager {
private:
struct FreeList { // Список с блоками определенного размера
FreeList* next; // Следующий FreeList
void* top_of_list; // Верх текущего списка
size_t chunk_size; // Размер каждого свободного блока
FreeList(FreeList* successor, size_t size) : next(successor),
top_of_list(NULL), chunk_size(size) {}
};
FreeList* all_lists; // Список всех FreeList
public:
MemManager() : all_lists(NULL) {}
void* Allocate(size_t bytes);
void Deallocate(void* space, size_t bytes);
};
void* MemManager::Allocate(size_t bytes)
{
for (FreeList* fl = all_lists;
fl != NULL && fl->chunk_size != bytes;
fl = fl->next)
{
if (fl->top_of_list != NULL)
{
void* space = fl->top_of_list;
fl->top_of_list = *((void**)(fl->top_of_list));
return space;
}
return ::operator new(bytes); // Пустой список
}
return ::operator new(bytes); // Такого списка нет
}
void MemManager::Deallocate(void* space, size_t bytes)
{
FreeList* fl = NULL;
for (fl = all_lists; fl != NULL; fl = fl->next)
if (fl->chunk_size == bytes) break;
if (fl == NULL) // Списка для такого размера нет
{
fl = new FreeList(all_lists, bytes);
all_lists = fl;
}
*((void**)space) = fl->top_of_list;
fl->top_of_list = space;
}
Функции Allocate() и Deallocate() вызываются из перегруженных операторов new и delete соответственно. Такой подход предельно упрощен. Им можно воспользоваться для любого сочетания классов, и он будет работать с производными классами, в которых добавились новые переменные. Он также может использоваться в схеме управления памятью на базе ведущих указателей [6].
Размещено на Allbest.ru
...Подобные документы
Цели объектно-ориентированного программирования, абстрактные классы и адреса базовых классов, множественное и виртуальное наследование. Инициализация элементов производного класса, программный вызов конструкторов базового и производного классов.
реферат [21,8 K], добавлен 31.10.2011Улучшение параметров модулей памяти. Функционирование и взаимодействие операционной системы с оперативной памятью. Анализ основных типов, параметров оперативной памяти. Программная часть с обработкой выполнения команд и размещением в оперативной памяти.
курсовая работа [99,5 K], добавлен 02.12.2009Сравнение различных способов обхода данных. Заполнение массива для случайного обхода. Изучение понятия кэш-памяти, ее основных размеров и функций. Оптимальный и неоптимальный алгоритм умножения двух матриц с точки зрения порядка обхода данных в памяти.
презентация [94,7 K], добавлен 02.06.2013Инициализация элементов данных класса в программе С++ с использованием конструктора, который запускается для каждого объекта. Применение операции ссылки в языке С++ для взятия адреса объекта. Деструкция как освобождение заказанной памяти, закрытие файлов.
реферат [20,1 K], добавлен 30.10.2011Понятие перегрузки (доопределения) операций и её разновидности. Пример соответствующей программы перегрузки, понятие полиморфизма и правила isA. Использование классов операторов в программах языка С++, конструкций операторов и производных классов.
реферат [19,9 K], добавлен 30.10.2011Создание программного обеспечения, позволяющего сортировать элементы числового массива в порядке возрастания или убывания их значений. Выбор языка программирования, среды разработки и построение алгоритма. Руководство пользователя и программиста.
курсовая работа [295,4 K], добавлен 07.04.2011Изучение определения, описания и вызова функций, указателей и ссылок на них. Написание функции умножения произвольного столбца двумерного массива на const. Умножение 2 столбцов массива на константы. Составление блок-схемы алгоритма и текста программы.
лабораторная работа [182,3 K], добавлен 09.01.2012- Управление памятью. Страничная организация памяти. Сегментная организация памяти. Виртуальная память
Как осуществляется трансляция адресов при страничной организации. Что такое компактировка и как с ее помощью избавиться от внешней фрагментации. Что такое регистр таблицы страниц, сегментация. Методы распределения памяти в виде отдельных сегментов.
контрольная работа [236,2 K], добавлен 23.12.2016 Механизм классов в C++. Инициализация внутреннего объекта с помощью конструктора. Управление доступом к классу. Защищенные члены класса. Графические средства компилятора Borland C 3.1. Библиотека стандартных шаблонов. Реализация и использование класса.
курсовая работа [2,7 M], добавлен 16.05.2012Основные типы циклов программирования. Методы применения специальных функций break, continue и цикла while. Обработка массивов информации. Условия применения циклических алгоритмов на языке программирования С++. Инициализация одномерного массива.
курсовая работа [1,7 M], добавлен 06.01.2014Разработка и реализация типовых алгоритмов обработки одномерных массивов на языке Delphi. Максимальный и минимальный элемент массива. Значение и расположение элементов массива. Элементы массива, находящиеся перед максимальным или минимальным элементом.
лабораторная работа [12,8 K], добавлен 02.12.2014Управление основной и вторичной памятью компьютера. Доступ пользователей к различным общим сетевым ресурсам. Система поддержки командного интерпретатора. Распределение ресурсов между пользователями, программами и процессами, работающими одновременно.
презентация [1,4 M], добавлен 24.01.2014Главная задача компьютерной системы. Виртуальные адресные пространства нескольких программ. Классификация методов распределения памяти. Зависимость загрузки процессора от числа задач и интенсивности ввода-вывода. Схема функционирования кэш-памяти.
презентация [2,2 M], добавлен 14.11.2012Определение размерности исходного массива на листе электронной таблицы, адреса ячейки. Считывание исходного массива в программу. Создание фрагмента программы для выполнения задания с использованием операторов условного перехода, адресация диапазонов.
контрольная работа [791,6 K], добавлен 16.04.2010Организация памяти компьютера и простые схемы управления ею. Принципы связывания адресов. Динамическое распределение и свопинг. Сегментная и сегментно-страничная организация памяти. Выталкивание редко используемой страницы. Описание работы с программой.
курсовая работа [3,1 M], добавлен 19.01.2016Архитектура компьютеров и возможности операционной системы по управлению памятью. Суть концепции виртуальной памяти. Аппаратно-независимые и аппаратно-зависимые средства управления виртуальной памятью. Сегментно-страничная организации виртуальной памяти.
презентация [355,2 K], добавлен 27.12.2010Массив как пронумерованная последовательность величин одинакового типа, обозначаемая одним именем. Расположение в последовательных ячейках памяти, обозначение именем массива и индексом, инициализация. Передача одномерных и двумерных массивов в функцию.
лабораторная работа [32,6 K], добавлен 06.07.2009Разработка на языке ассемблера алгоритма контроля, на циклический CRC-код, массива данных хранящегося в некоторой области памяти. Сохранение кода для последующей периодической проверки массива данных. Сообщение об искажении данных. Описание алгоритма.
курсовая работа [453,0 K], добавлен 27.02.2009Сравнительный анализ статической и динамической памяти. Быстродействие и потребление энергии статической памятью. Объем памяти микросхем. Временные диаграммы чтения и записи памяти. Микросхемы синхронной и асинхронной памяти. Режимы модулей памяти.
презентация [114,2 K], добавлен 27.08.2013Разработка алгоритма работы и структуры контроллера кэш-памяти с полностью ассоциативным отображением основной памяти. Представление операционной и управляющей частей черного ящика устройства. Схема алгоритма контроллера кэш на уровне микроопераций.
курсовая работа [1,0 M], добавлен 19.03.2012