фрагментация tcmalloc

Наше программное обеспечение реализует систему модели актера, и мы очень часто выделяем / освобождаем маленький объект. Я уверен, что каждый объект будет уничтожен без утечки памяти. (Я использовал утилиты valgrind и tcmalloc для проверки утечки памяти в моем программном обеспечении. Утечки не обнаружено.)

Когда мы изменили использование tcmalloc для замены malloc в glibc, мы обнаружили, что объем памяти постоянно увеличивается до тех пор, пока OOM (Out of Memory) не завершит процесс.
Затем мы обнаружили, что glibc также имеет ту же проблему, но скорость увеличения меньше, чем у tcmalloc.

Я использовал malloc_stats (), чтобы показать информацию о памяти

после первого исполнения (топ шоу 0,96G) ‘


  • MALLOC: 960110592 (915,6 МБ) Размер кучи
  • MALLOC: 15886016 (15,2 МБ) байт, используемых приложением
  • MALLOC: 907419648 (865,4 МБ) Байт в куче страниц
  • MALLOC: 0 (0,0 МБ) байтов, не отображенных в куче страниц
  • MALLOC: 27121208 (25,9 МБ) Свободных байт в центральном кеше
  • MALLOC: 151040 (0,1 МБ) байт свободно в кеше передачи
  • MALLOC: 9532680 (9,1 МБ) Байт свободно в кэшах потоков
  • MALLOC: 14275 пролетов в использовании
  • MALLOC: используется 27 куч
  • MALLOC: 7602176 (7,2 МБ) Метаданные выделены

После 5-го такого же исполнения (топ шоу 1.2G)

  • MALLOC: 1173131264 (1118,8 МБ) Размер кучи
  • MALLOC: 18001048 (17,2 МБ) Байт используется приложением
  • MALLOC: 1082458112 (1032,3 МБ) Байт в куче страниц
  • MALLOC: 21168128 (20,2 МБ) байтов, не отображенных в куче страниц
  • MALLOC: 37992328 (36,2 МБ) Свободных байт в центральном кеше
  • MALLOC: 252928 (0,2 МБ) Байт свободно в кеше передачи
  • MALLOC: 13258720 (12,6 МБ) Байт свободно в кэшах потоков
  • MALLOC: 17651 пролет в использовании
  • MALLOC: используется 27 куч
  • MALLOC: 8126464 (7,8 МБ) Метаданные выделены

Мы можем видеть из полученных данных.
после 5-го поведения в нашем программном обеспечении будет использоваться только 17.2. Но tcmalloc хранит 1.1G памяти без возврата в систему. Конечно, это не имеет значения, что tcmalloc хранит эту память.
Но оно продолжает расти, когда наша программа убивается OOM (фактическая используемая память меньше 1G).

У нас есть сомнения, что это связано с фрагментацией кучи.
Кто-нибудь может поделиться с нами своим опытом?
Я думаю, что у меня такая же ситуация, как
https://bugzilla.redhat.com/show_bug.cgi?id=843478

Спасибо большое.

3

Решение

Я бы предложил использовать Консервативный Бем и использовать GC_MALLOC а также GC_MALLOC_ATOMIC вместо malloc в вашем приложении (и GC_FREE вместо free, но вы могли бы даже избежать каких-либо явных free-G, GC сделает их). Или, может быть, использовать Valgrind (с системой Glibc malloc), чтобы найти утечки памяти. При использовании Boehm GC не забудьте явно очистить выделенные зоны памяти.

Было бы предпочтительнее убедиться, что ваши мелкие объекты имеют крупнозернистые размеры. Например. выделяйте объекты из 8, 12 или 16 слов, а не объекты из 8, 9, 10, 11, 12, 13, 14, 15 или 16 слов … Например, вы можете выделить только зоны размером с степень 2 или 3 раз сила 2.

Кроме того, не забывайте, что вы можете ограничить пространство памяти с setrlimit (2), например с ulimit встроенный в Bash работает в вашем терминале. Это должно облегчить тестирование. Также, возможно, используя pmap или же /proc/$(pidof yourapp)/maps может помочь вам понять используемое адресное пространство.

PS. Ни Boehm GC, ни какой-либо malloc (в том числе tcmalloc или Глибц malloc) может справиться с фрагментацией памяти. Если вы подозреваете фрагментацию, вы должны перемещать зоны памяти в адресном пространстве (то есть вы можете захотеть кодировать свой точный, копирующий, поколенческий GC или повторно использовать какой-либо существующий).

1

Другие решения

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

сделай это :

MallocExtension :: экземпляр () -> ReleaseFreeMemory ();

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

Посмотрите раздел «Освобождение памяти обратно в систему» ​​для получения дополнительной информации.
http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html

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

1

По вопросам рекламы [email protected]