Наше программное обеспечение реализует систему модели актера, и мы очень часто выделяем / освобождаем маленький объект. Я уверен, что каждый объект будет уничтожен без утечки памяти. (Я использовал утилиты valgrind и tcmalloc для проверки утечки памяти в моем программном обеспечении. Утечки не обнаружено.)
Когда мы изменили использование tcmalloc для замены malloc в glibc, мы обнаружили, что объем памяти постоянно увеличивается до тех пор, пока OOM (Out of Memory) не завершит процесс.
Затем мы обнаружили, что glibc также имеет ту же проблему, но скорость увеличения меньше, чем у tcmalloc.
Я использовал malloc_stats (), чтобы показать информацию о памяти
после первого исполнения (топ шоу 0,96G) ‘
Мы можем видеть из полученных данных.
после 5-го поведения в нашем программном обеспечении будет использоваться только 17.2. Но tcmalloc хранит 1.1G памяти без возврата в систему. Конечно, это не имеет значения, что tcmalloc хранит эту память.
Но оно продолжает расти, когда наша программа убивается OOM (фактическая используемая память меньше 1G).
У нас есть сомнения, что это связано с фрагментацией кучи.
Кто-нибудь может поделиться с нами своим опытом?
Я думаю, что у меня такая же ситуация, как
https://bugzilla.redhat.com/show_bug.cgi?id=843478
Спасибо большое.
Я бы предложил использовать Консервативный Бем и использовать 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 или повторно использовать какой-либо существующий).
tcmalloc пытается сделать некоторые умные вещи, чтобы предвидеть использование вашей памяти, но не очень хорошо возвращать память в систему, даже после того, как вы ее освободили. на самом деле, он может находиться в памяти и вести к ООМ.
сделай это :
MallocExtension :: экземпляр () -> ReleaseFreeMemory ();
когда ваше приложение ожидаемо освободило память, которую оно ожидает не использовать в ближайшее время.
Посмотрите раздел «Освобождение памяти обратно в систему» для получения дополнительной информации.
http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html
Существуют и другие методы, такие как установка скорости выпуска, но для начала вы можете добавить это в свой код и проверить, уменьшается ли резидентная память, как вы ожидаете.