Inta[ n ]; // ошибка, размер нельзя вычислить во время компиляции

int* p = new int[ n ]; // ок, используется значение во время выполнения

delete[] p;

}

 

Каждое динамическое выделение, помимо запрашиваемого пользовательского объема, расходует некоторый дополнительный объем служебных данных, размер которого сильно варьируется в зависимости от среды разработки, ее версии и конфигурации сборки. Например, Visual Studio 2010 в отладочной конфигурации дополнительно к запрашиваемой памяти выделяет еще 36 байт для внутренних нужд отладчика. Соответственно, при слишком малых объемах выделения удельный вес служебной памяти может превышать удельный вес полезной памяти.

 

П
Служебные данные 36 байт
Объект 12 байт
П
Служебные данные 36 байт
Объект 830 байт
Маленький объект - служебных данных больше, чем нужных!
Большой объект - служебных данных меньше, чем нужных

 

Случайное повреждение служебной части динамически выделенной памяти также может привести к фатальному завершению программы, при этом обнаружить момент повреждения очень сложно, поскольку проблема обычно проявляется в момент освобождения памяти, что значительно позже момента повреждения.

 

При написании программ с повышенными требованиями к производительности к динамическому выделению памяти следует подходить очень внимательно. Обычно динамическое выделение памяти работает эффективнее для крупных блоков данных по сравнению с мелкими. Кроме того, выделение и освобождение памяти требует немалой порции времени, что может быть очень заметным в крупных программах. Временная доля для выделения+освобождения динамической памяти часто превышает 30% от общего времени выполнения.

 

Если память, которая более не используется программой, не освобождать, возникает явление утечки памяти (memory leak). Выделенный блок помечен распределителем динамической памяти как используемый, однако в программе не содержится ни одной переменной-указателя, хранящей его адрес, что делает его недоступным. В результате, блок никак не используется до завершения выполнения программы. Он не освобождается ни для других программ, ни для других блоков внутри данной программы.

 

intmain ()

{

int* p = new int[ 10000000 ]; // Выделить выделили, а освобождать кто будет?

...

}

 

Для маленьких программ это явление возможно не имеет огромного значения, однако для больших программ, особенно для работающих в режиме 24x7, таких как веб-серверы, наличие значительного объема утечек памяти рано или поздно приводит к ее исчерпанию, а значит к последующему фатальному завершению.

 

Куча  
Утечка 1
Утечка 2
Утечка 3
Все, что осталось от памяти

 

Обнаружение утечек памяти является весьма нетривиальной задачей, требующей специальных инструментов для трассировки выделения и освобождения. Наилучшими методами предотвращения утечек памяти является аккуратность разработчика, а также применение “умных” указателей (std::unique_ptr, std::shared_ptr). Начинающих программистов, недостаточно аккуратно следящих за освобождением памяти, часто сравнивают с людьми, которые не моют за собой посуду после приема пищи - рано или поздно чистые тарелки заканчиваются.

 

При интенсивной работе с кучей, имеет место также более сложное явление фрагментации, когда распределитель памяти не может выделить цельный блок стоящий подряд, хотя имеется достаточное общее свободное пространство в виде нескольких меньших блоков.

 

Куча (1Gb всего, 350Мб свободно)  
Занято 170Мб
Занято 130Мб
Занято 350Мб
Свободно 200Мб
Свободно 150Мб
Необходимо 220Мб
220 < 350но цельного свободного блока в наличии нет из-за фрагментации кучи!

 

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

 

 








Дата добавления: 2016-01-29; просмотров: 1276;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.009 сек.