我们的软件实现了一个actor模型系统,我们经常分配/释放小对象。我非常确定每个对象都会被销毁而不会发生内存泄漏。(我已经使用 valgrind 和 tcmalloc 工具检查了我的软件中的内存泄漏。没有发现泄漏。)
当我们改用 tcmalloc 替换 glibc 中的 malloc 时,我们发现内存不断增加,直到进程被 OOM(Out of Memory)杀死。然后我们发现 glibc 也有同样的问题,但是增长率低于 tcmalloc。
我使用 malloc_stats() 来显示内存信息
首次执行后(顶部显示 0.96G)'
- MALLOC:960110592(915.6 MB)堆大小
- MALLOC:15886016 (15.2 MB) 应用程序正在使用的字节数
- MALLOC:907419648(865.4 MB)页堆中的可用字节
- MALLOC: 0 ( 0.0 MB) 在页堆中未映射的字节
- MALLOC:27121208(25.9 MB)中央缓存中的可用字节
- MALLOC:151040(0.1 MB)传输缓存中的可用字节
- MALLOC:9532680(9.1 MB)线程缓存中的可用字节
- MALLOC:14275 跨度正在使用中
- MALLOC:27 个线程堆正在使用中
- MALLOC: 7602176 (7.2 MB) 已分配元数据
第 5 次相同执行后(顶部显示 1.2G)
- MALLOC:1173131264(1118.8 MB)堆大小
- MALLOC:18001048(17.2 MB)应用程序正在使用的字节
- MALLOC:1082458112(1032.3 MB)页堆中的可用字节
- MALLOC:21168128(20.2 MB)字节未映射到页堆中
- MALLOC:37992328(36.2 MB)中央缓存中的可用字节
- MALLOC:252928(0.2 MB)传输缓存中的可用字节
- MALLOC:13258720(12.6 MB)线程缓存中的可用字节
- MALLOC: 17651 使用中的跨度
- MALLOC:27 个线程堆正在使用中
- MALLOC: 8126464 (7.8 MB) 已分配元数据
我们可以从这样的数据中看出。在第 5 次相同的行为之后,我们的软件中只使用了 17.2。但是 tcmalloc 持有 1.1G 内存,不返回系统。当然,tcmalloc 持有那些内存也没关系。但是当我们的程序被OOM杀死时它会不断增加(实际使用的内存小于1G)。
我们怀疑它与堆碎片有关。有人有经验可以和我们分享吗?我想我的情况和 https://bugzilla.redhat.com/show_bug.cgi?id=843478一样
非常感谢。