内容:
我有一个应用程序,它应该消耗更多的内存(大约约为预期数量的250%),但我似乎无法找到任何内存泄漏。调用相同的函数(执行大量分配)会使内存使用量增加到某个点,然后它就不会改变并保持不变。
计划详情:
应用程序使用四叉树数据结构来存储“点数”。可以指定要存储在内存中的最大点数(高速缓存大小)。 'Points'存储在'PointBuckets'(链接到四叉树的叶节点的点数组)中,如果达到四叉树中的最大总点数,则将其序列化并保存到临时文件中,以便在需要。这一切似乎都很好。
现在,当加载文件时,会创建一个新的四叉树,如果它存在则删除旧的四叉树,然后从文件中读取点并逐个插入四叉树。在节点拆分等过程中创建和删除存储桶时会发生大量内存分配。
症状:
如果我加载一个预计会使用300MB内存的文件,我会得到预期的内存消耗量。都好。如果我一遍又一遍地加载相同的文件,内存使用量会不断增长(我正在看顶部的RES列,Linux)直到大约700MB。这可能表明存在内存泄漏。但是,如果我继续加载文件,内存消耗将保持在700MB。
另一件事:当我使用valgrind massif并查看内存使用情况时,它始终保持在预期的限制范围内。例如,如果我将缓存大小指定为1.5 GB并单独运行我的程序,它最终将消耗4GB内存。如果我在massif中运行它,它将始终保持在2GB以下,然后在生成的图形中,我将能够看到它实际上从未分配超过预期的1.5GB。我天真的假设是,这是因为massif使用自定义内存池,以某种方式防止碎片。
那么您认为这是怎么回事?如果是内存碎片,我应该寻求什么样的解决方案才能解决这个问题?
答案 0 :(得分:3)
我更多地介绍了简单的分配器和操作系统缓存行为。它们保留您分配的内存而不是释放它,以便在您下次请求时以更快速的方式返回给您。然而,对于这种效果,250%确实听起来很多 - 你可能会看到碎片问题。
尝试将分配器交换为无碎片分配器,如对象池或内存竞技场。