Управление памятью в С++

Инициализация массива, элементы которого содержат количество дней в каждом месяце года. Управление выделением памяти в С++. Перегрузка операторов 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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.