最大限度地减少C程序中的内存占用

时间:2010-11-27 15:29:31

标签: c linux memory memory-management unix

在Linux(* nix)上最小化C程序中的内存占用量有哪些选择?

据我所知,libc malloc()正在使用brk()或mmap()。由于内存碎片,通常无法返回使用brk()分配的内存。

我的程序应该全天候工作,它会执行很多malloc() - s和free() - s。启动后,RSS上升到大约100Mb。这太过分了,因为我确信在任何特定时刻内存中的数据都不到100 Mb。

可能是brk()碎片问题。

那么,我的选择在哪里?

我应该使用另一个只使用mmap()的malloc()实现吗? 我应该做别的吗? 关于内存占用问题,我能阅读一些内容吗?

感谢。

2 个答案:

答案 0 :(得分:11)

如果您的程序有如此多的mallocfree次调用,则会出现这种碎片,每次分配使用mmap将会非常缓慢。相反,你需要衡量导致内存碎片的原因并修复它。首先,我将使用像valgrind这样的工具来确保它实际上不是内存泄漏/损坏问题导致过多的内存使用。然后,为了确认问题的原因是碎片,我将使用您自己的包装器将所有调用包装到mallocfree,该包装器递增和递减“总分配字节数”变量,以便您可以,在任何时候,比较理论和实际的内存消耗。

如果事实证明碎片是问题,那么好的第一步就是看看你为什么要进行如此多的小型短期分配。如果你可以消除它们,而是在一个块中分配一个特定的任务/数据对象所需的所有内存,然后自己砍掉它,你不仅可以摆脱最糟糕的碎片,还可以提高代码的性能。一点点。每次调用mallocfree都会产生很大的开销,尤其是在需要同步/锁定的线程环境中。将所有相关数据保存在一个分配的块中也可以减少或消除编写特殊代码以释放包含指针的结构的需要;单次调用free通常就足够了(虽然为了保持实现不透明,你仍然应该用foo_free函数包装它。)

答案 1 :(得分:2)

除非您正在分配固定大小的块 - 或执行某种定期垃圾收集 - 否则您的内存占用量可能会超出由于碎片而导致的内容。

free()无法将内存返回给操作系统,除非未使用完整页面。

我的建议是使用slab allocation计划。预分配几个内存池。每个池将用于相似大小的对象(理想情况下大小相同)。通过这种方式,您可以避免碎片并保持RSS占用空间不变(尽管由于预分配而大于绝对必要)。