避免内存碎片的方法

时间:2013-04-06 08:12:14

标签: c++ memory-management rtos

我从RTOS分配了一个大内存池(我已经知道我的应用程序内存需求,它不会超过一定的大小)。然后我的应用程序分配请求就从该池中完成。

最近我开始面临一个问题;即使存在内存,也没有实现分配请求(集成了内存台标记框架,显示了这一点),调查显示我们正在遭受内存碎片化。

我的应用程序严重依赖于STL(也接收来自网络的数据,XML解析,图像处理,将其保存为PNG等),以及内存碎片后面的堆内存分配(还有其他原因吗?),什么是最好的避免它的方法?

3 个答案:

答案 0 :(得分:3)

内存碎片的典型原因是随着池的老化,大内存块会被拆分为越来越小的块。避免这种情况的简单方法是固定尺寸。

这显然无法解决使用18MB存储空间的问题,其中每个XML节点都存储为一个小字符串,然后尝试加载4096 x 4096 x 8位PNG(16MB),如果您的池为24MB ,因为XML会将你的内存分成很小的一部分,然后你需要16MB的连续内存。但是“固定大小”将避免<aaa>b</aaa>的XML字符串占用4个字节和2个字节的内存,从而使得内存对于存储在那里的任何其他内容完全无用,因为没有其他对象是4或2个字节长。

此方法将要求您的内存分配器编写为考虑“固定大小”。

答案 1 :(得分:2)

第一步是查看RTOS是否为低碎片堆提供了任何机制。

如果没有,请查看其他人是否已经实现了低碎片分配器。 related question(来自右侧栏)提供了一个示例。

第三,如果没有其他现有解决方案可行,则解决方案是使用多个内存池进行分配。

服务从一个池中大小为1到X字节的短期分配,以及从另一个池到大小为1到X字节的长期分配。

类似于大小X + 1到2X,2X +1到4X,4X + 1到8X的分配等等。 (您可以尝试其他铲斗尺寸......)

要确定X的最佳尺寸,您需要分析您的应用并查看每种分配尺寸的频率。

确保每个存储桶都有足够的空间来完成分配:)

答案 2 :(得分:0)

假设:切换到垃圾回收。您需要一个压缩垃圾收集器,一个能够物理移动分配的数据,否则它将无法帮助碎片。

  • 垃圾收集不一定与实时要求不兼容。实时意味着“您的系统必须保证在特定期限内做出反应”。如果垃圾收集器以递增的方式工作并且可以保证足够短的“握住世界” - 相,那么你就没事了。
  • 现代垃圾收集器的表现并非全是坏事。人们总是倾向于忘记freedelete也是相当昂贵的操作。
  • 对垃圾收集进行权衡:最有效的垃圾收集有很长的时间。那些持有短暂世界阶段的人整体效率较低。

不幸的是,所有这些都是假设的,因为我目前还不知道C ++的任何压缩,增量垃圾收集器。除了C ++ / CLI之外。