Утечка памяти при использовании malloc не удается - PullRequest
3 голосов
/ 17 августа 2010

Я пишу программу для утечки памяти (основной памяти), чтобы проверить, как система ведет себя с нехваткой системной памяти и подкачки памяти.Мы используем следующий цикл, который периодически запускается и приводит к утечке памяти

main(int argc, char* argv[] )  
{
   int arg_mem = argv[1];

        while(1)
        {
          u_int_ptr =(unsigned int*)  malloc(arg_mem * 1024 * 1024);

        if( u_int_ptr == NULL )
           printf("\n leakyapp Daemon FAILED due to insufficient available memory....");

          sleep( arg_time );
        }

}

Вышеупомянутый цикл выполняется некоторое время и печатает сообщение «leakyapp Daemon FAILED из-за недостатка доступной памяти ....».Но когда я запускаю команду «free», я вижу, что запуск этой программы не влияет ни на основную память, ни на подкачку.

Я что-то не так делаю?

Ответы [ 6 ]

8 голосов
/ 17 августа 2010

Физическая память не выделяется для ваших выделений, пока вы на самом деле не записываете в нее.

Если у вас версия ядра после 2.6.23, используйте mmap() с флагом MAP_POPULATE вместо malloc():

u_int_ptr = mmap(NULL, arg_mem * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);

if (u_int_ptr == MAP_FAILED)
    /* ... */

Если у вас более старое ядро, вам нужно будет коснуться каждой страницы в выделении.

3 голосов
/ 17 августа 2010

Может быть какая-то оптимизация копирования при записи.Я бы предложил записать что-то в память, которую вы выделяете.

1 голос
/ 17 августа 2010

Происходит следующее: malloc запрашивает argmem * 256 страниц из кучи (при условии размера страницы 4 Кбайт). Куча в свою очередь запрашивает память у операционной системы. Однако все, что делает, это создает записи в таблице страниц для вновь выделенного блока памяти. Фактическое физическое ОЗУ не выделяется для процесса, кроме того, которое требуется куче для отслеживания запроса malloc.

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

Поскольку все новые страницы начинают полностью обнуляться, Linux может использовать стратегию «копирования при записи» для оптимизации размещения страниц. то есть он может сохранять одну страницу полностью обнуленной и всегда выделять ее, когда процесс пытается прочитать с ранее неиспользованной страницы. Только когда процесс попытается записать на эту новую страницу, он фактически выделит полностью свежую страницу из физической памяти. Я не знаю, действительно ли Linux это делает, но если это так, простого чтения с новой страницы недостаточно для увеличения использования физической памяти.

Итак, ваша лучшая стратегия - выделить большой блок оперативной памяти, а затем записать что-нибудь с интервалом в 4096 байт.

0 голосов
/ 17 августа 2010

Я думаю, что кафе уже объяснили это.Linux обычно настроен на перегрузку памяти.Вы выделяете огромные порции памяти, но внутри ничего не происходит, кроме как просто сделать заметку, что процесс обрабатывает эту огромную порцию памяти.Не раньше, чем вы попытаетесь записать этот фрагмент, ядро ​​пытается найти свободную виртуальную память, чтобы удовлетворить права на чтение / запись.Это немного похоже на бронирование авиабилетов: авиакомпании обычно перебронируют рейсов, потому что всегда есть процент пассажиров, которые не появляются.чанк с memset() после выделения.calloc тоже должно работать.

0 голосов
/ 17 августа 2010

Я предполагаю (основываясь на аргументе командной строки), что вы используете настольную / серверную ОС, а не встроенную систему.

Такое распределение памяти, вероятно, не занимает много ОЗУ.Выделение памяти может даже не удаться - в некоторых ОС (например, в Linux) malloc() может возвращать значение, отличное от NULL, даже если вы запрашиваете больше памяти, чем доступно.То, что вы пытаетесь проверить, трудно предложить что-то конкретное, но вы можете рассмотреть более низкоуровневые способы выделения памяти, чем malloc(), или способы управления системой виртуальной памяти.В Linux вы можете посмотреть на mlock().

0 голосов
/ 17 августа 2010

Что печатает ulimit -m -v?

Объяснение: На любой серверной ОС вы можете ограничить количество ресурсов, которое может выделить процесс, чтобы убедиться, что один сбежавший процесс не может остановить всю машину.

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