Диагностировать фрагментацию кучи в Mac OS X? - PullRequest
2 голосов
/ 09 февраля 2012

Приложение Core Foundation, которое я пишу, похоже, потребляет гораздо больше памяти (согласно подсчету "Real Mem" в Activity Monitor), чем я когда-либо выделяю.

Я подтвердил, что мои фактические выделения соответствуют ожидаемым (около 10 МБ) с помощью представления «Распределение байтов в реальном времени» в «Инструментах», но счет «Реальная память» в Activity Monitor показывает> 60 МБ и, очевидно, растет.Я также подтвердил, что нет утечек, также используя Instruments.

Мое приложение поддерживает большую очередь буферов различного размера и постоянно добавляет буферы free () и malloc () по мере добавления/ удаляет элементы очереди.

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

  1. Есть ли способ подтвердить это на OS X, например, возможно получить визуальное представление кучи?
  2. Есть ли необязательный менеджер кучи с низкой фрагментацией для OS X, как для Windows?

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

#define MAX_SIZE (10*1024*1024)

int main (int argc, const char * argv[])
{

size_t actual_alloc=0;
size_t max_alloc=0;

char *bigbuf=NULL;
size_t bigsize=0;

for  (long x=0; x<10000000; x++)
{
    if (bigbuf!=NULL)
    {
        actual_alloc -= bigsize;
        free(bigbuf);
    }

    bigsize = rand() % MAX_SIZE; // alloc random amount up to MAX_SIZE
    bigbuf = (char*)malloc(bigsize);
    memset(bigbuf, 'x', bigsize);
    actual_alloc += bigsize;

    if (actual_alloc > max_alloc)
        max_alloc = actual_alloc;

    if (x%100==0)
    {
        printf("alloc = %u \t max = %u\n", 
             (unsigned long)actual_alloc, (unsigned long)max_alloc);

        // max_alloc tends towards 10MB, 
        //  "Real Mem" in activity monitor tends towards 60MB
    }
}


return 0;
}

Если вы удалите случайный элемент из приведенного выше кода, вы получите около 10 МБ памяти процесса, как и ожидалось.

1 Ответ

2 голосов
/ 09 февраля 2012

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

Невозможно предвидеть поведение подсистемы выделения памяти или других системных библиотек, с которыми вы ссылаетесь, и, следовательно, Activity Monitor или top или любой другой инструмент не даст вам значимой информации. Если вы хотите отслеживать выделения памяти или утечки, используйте отладчик malloc или такой инструмент, как valgrind.

...