Минимизация использования памяти в программах на C - PullRequest
9 голосов
/ 27 ноября 2010

Каковы мои варианты минимизации объема памяти в программах на C в Linux (* nix)?

Насколько я знаю, libc malloc () использует либо brk (), либо mmap (). Память, выделенная с помощью brk (), обычно не может быть возвращена из-за фрагментации памяти.

Моя программа должна работать 24/7, и она выполняет много функций malloc () и free (). После запуска RSS увеличивается примерно до 100 МБ. Это слишком много, потому что я точно знаю, что в любой конкретный момент в памяти меньше 100 МБ данных.

Вероятно, это проблема фрагментации brk ().

Итак, каковы мои варианты здесь?

Должен ли я использовать другую реализацию malloc (), которая использует только mmap ()? Должен ли я сделать что-то еще? Могу ли я прочитать что-то, касающееся проблемы с объемом памяти?

Спасибо.

Ответы [ 2 ]

11 голосов
/ 27 ноября 2010

Если в вашей программе так много вызовов malloc и free, что вы получаете такую ​​фрагментацию, использование mmap для каждого выделения будет безнадежно медленным. Вместо этого вам нужно измерить, что вызывает фрагментацию памяти и исправить это. Сначала я бы использовал такой инструмент, как valgrind, чтобы убедиться, что это не проблема утечки / повреждения памяти, вызывающая чрезмерное использование памяти. Затем, чтобы подтвердить, что причиной проблемы является фрагментация, я бы обернул все вызовы malloc и free вашей собственной оберткой, которая увеличивает и уменьшает переменную «общего количества выделенных байтов», чтобы вы могли в любой момент сравните теоретическое и фактическое потребление памяти.

Если выясняется, что проблема заключается в фрагментации, первым хорошим шагом будет выяснить, почему вы делаете так много небольших, недолговечных распределений. Если вы можете устранить их и вместо этого распределить всю память, которая потребуется конкретному объекту задачи / данным в одном блоке, то разбейте его на части самостоятельно, вы не только избавитесь от наихудшей фрагментации, но и значительно улучшите производительность своего кода. немного. Каждый вызов malloc или free требует значительных накладных расходов, особенно в многопоточной среде, где необходима синхронизация / блокировка. Хранение всех связанных данных в одном выделенном блоке также может уменьшить или исключить необходимость написания специального кода для свободных структур, содержащих указатели; часто бывает достаточно одного вызова free (хотя для сохранения непрозрачности реализации вы все равно должны обернуть это функцией foo_free).

2 голосов
/ 27 ноября 2010

Если вы не выделяете блоки фиксированного размера - или не выполняете какой-то периодический сбор мусора - ваш объем памяти, вероятно, вырастет за пределы того, что требуется из-за фрагментации.

free() не может вернуть память в ОС, если не используются полные страницы.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...