4

概括:

我有一个应用程序消耗更多的内存(大约是预期数量的 250%),但我似乎找不到任何内存泄漏。调用相同的函数(执行大量分配)将不断增加内存使用量到某个点,然后它不会改变并停留在那里。

计划详情:

该应用程序使用四叉树数据结构来存储“点”。可以指定要存储在内存中的最大点数(缓存大小)。'Points' 存储在 'PointBuckets' (链接到四叉树的叶节点的点数组)中,如果达到四叉树中的最大总点数,则将其序列化并保存到临时文件中,以便在何时检索需要。这一切似乎都很好。

现在,当加载文件时,会创建一个新的四叉树,如果旧的四叉树存在则删除它,然后从文件中读取点并一一插入四叉树。在节点拆分等过程中创建和删除存储桶时,会发生大量内存分配。

症状:

如果我加载一个预期使用 300MB 内存的文件,我会得到预期的内存消耗量。都好。如果我一遍又一遍地加载相同的文件,内存使用量会不断增长(我正在查看顶部的 RES 列,Linux)直到大约 700MB。这可能表明内存泄漏。但是,如果我继续加载文件,内存消耗将保持在 700MB。

另一件事:当我使用 valgrind massif 并查看内存使用情况时,它始终保持在预期的限制内。例如,如果我将缓存大小指定为 1.5 GB 并单独运行我的程序,它最终会消耗 4GB 的内存。如果我在地块中运行它,它将一直保持在 2GB 以下,然后在生成的图表中我将能够看到它实际上从未分配超过预期的 1.5GB。我幼稚的假设是,发生这种情况是因为 massif 使用了一个自定义内存池,它以某种方式防止了碎片。

那么你认为这里发生了什么?如果是内存碎片,我应该寻找什么样的解决方案来解决这个问题?

4

1 回答 1

3

我会把它更多地放在简单的分配器和操作系统缓存行为上。它们保留您分配的内存而不是释放它,以便在您下次请求时以更迅速的方式将其返回给您。然而,对于这种效果来说,250% 听起来确实很多——你可能会看到碎片问题。

尝试将您的分配器换成无碎片的分配器,如对象池或内存区域。

于 2012-07-11T17:25:19.350 回答