我从RTOS分配了一个大内存池(我已经知道我的应用程序内存需求,它不会超过一定的大小)。然后我的应用程序分配请求就从该池中完成。
最近我开始面临一个问题;即使存在内存,也没有实现分配请求(集成了内存台标记框架,显示了这一点),调查显示我们正在遭受内存碎片化。
我的应用程序严重依赖于STL(也接收来自网络的数据,XML解析,图像处理,将其保存为PNG等),以及内存碎片后面的堆内存分配(还有其他原因吗?),什么是最好的避免它的方法?
答案 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)
假设:切换到垃圾回收。您需要一个压缩垃圾收集器,一个能够物理移动分配的数据,否则它将无法帮助碎片。
free
和delete
也是相当昂贵的操作。不幸的是,所有这些都是假设的,因为我目前还不知道C ++的任何压缩,增量垃圾收集器。除了C ++ / CLI之外。