我们的软件实现了一个actor模型系统,我们经常分配/释放小对象。我非常确定每个对象都会在没有内存泄漏的情况下被销毁。 (我使用了valgrind和tcmalloc工具来检查我的软件中的内存泄漏。没有发现泄漏。)
当我们更改为使用tcmalloc替换glibc中的malloc时,我们发现内存不断增加,直到该进程被OOM(内存不足)终止。 然后我们发现glibc也有同样的问题,但增长率低于tcmalloc。
我使用malloc_stats()来显示内存信息
首次执行后(顶部显示0.96G)'
从这样的数据我们可以看出。 在第5次相同的行为之后,我们的软件中只使用了17.2。但tcmalloc保持1.1G内存而不返回系统。当然,tcmalloc保持那些记忆并不重要。 但是当我们的程序被OOM杀死时(实际使用的内存小于1G),它会不断增加。
我们怀疑它与堆碎片有关。 有人有经验可以与我们分享? 我想我有同样的情况 https://bugzilla.redhat.com/show_bug.cgi?id=843478
非常感谢。
答案 0 :(得分:1)
我建议您在应用中使用Boehm's conservative GC并使用GC_MALLOC
和GC_MALLOC_ATOMIC
代替malloc
(而GC_FREE
代替free
,但是你甚至可以避免任何明确的free
,GC会做到这一点。或者可以使用valgrind(使用系统Glibc malloc)来查找内存泄漏。如果使用Boehm的GC,请不要忘记明确清除分配的内存区域。
最好确保您的许多小物件具有粗粒度。例如。分配8或12或16个单词的对象,而不是8,9,10,11,12,13,14,15或16个单词的对象...例如,您可能只分配一些大小为2或3的幂的区域倍于2的力量。
此外,请不要忘记您可以使用setrlimit(2)限制内存空间,例如在终端中运行bash的内置ulimit
。这应该简化测试。此外,使用pmap
或/proc/$(pidof yourapp)/maps
可能有助于您了解所使用的地址空间。
PS。 Boehm GC,无论任何类型的malloc
(包括tcmalloc
或Glibc malloc
)都不能解决内存碎片问题。如果您怀疑存在碎片,则必须在地址空间中移动内存区域(即您可能希望编写自己的精确,复制,分代GC或重新使用现有GC)。
答案 1 :(得分:1)
tcmalloc尝试做一些聪明的事情来预测你的内存使用,但是即使你已经释放内存,将内存释放回系统也不是很好。事实上,它可能驻留在内存中并导致OOM。
这样做:
MallocExtension ::实例() - > ReleaseFreeMemory();
当你的应用程序预计会释放它预计不会很快使用的内存时。
请查看“将内存释放回系统”部分以获取更多信息 http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html
还有其他方法,例如设置发布速率,但作为一个开始,您可以在代码中使用它,并检查驻留内存是否按预期停机。