我从RTOS中分配一个大的内存池(我已经知道我的应用程序内存要求,它不会超过一定的大小)。然后我的应用程序分配请求将从该池中完成。避免内存碎片的方法
最近我开始面临一个问题;即使内存在那里(得到集成的内存基准标记框架,显示了这一点),分配请求并没有得到满足,调查显示我们正在遭受内存碎片化。我的应用程序严重依赖于STL(也接收来自网络的数据,XML解析,图像处理,将其保存为PNG等),并作为内存碎片后面的堆内存分配(是否还有其他原因?),什么是最好的方法来避免它?
我从RTOS中分配一个大的内存池(我已经知道我的应用程序内存要求,它不会超过一定的大小)。然后我的应用程序分配请求将从该池中完成。避免内存碎片的方法
最近我开始面临一个问题;即使内存在那里(得到集成的内存基准标记框架,显示了这一点),分配请求并没有得到满足,调查显示我们正在遭受内存碎片化。我的应用程序严重依赖于STL(也接收来自网络的数据,XML解析,图像处理,将其保存为PNG等),并作为内存碎片后面的堆内存分配(是否还有其他原因?),什么是最好的方法来避免它?
内存碎片的典型原因是随着池老化,大内存块会被分割成越来越小的块。避免这种情况的简单方法是具有固定大小。
这显然不能解决使用18MB存储XML的问题,其中每个XML节点存储为一个小字符串,然后尝试加载4096 x 4096 x 8位PNG(16MB),如果您的池是24MB,因为XML会将你的内存分成很小的一部分,然后你需要16MB的连续内存。但“固定大小”将避免一个XML字符串<aaa>b</aaa>
占用4个字节和2个字节的内存,从而使内存完全无用于存储在那里的任何其他对象,因为没有其他对象是4或2个字节长。
该方法将要求您的内存分配器正在写入以考虑“固定大小”。
我同意。将您的游泳池分成多个桶,每个桶只分发固定大小的块。 – 2013-04-06 08:28:34
第一步是查看RTOS是否为低碎片堆提供了任何机制。
如果不是,请查看是否有其他人已经实施了低碎片分配器。 A related question(来自右侧栏)提供了一个示例。
第三,如果没有其他现有的解决方案工作,解决方案将是使用多个内存池进行分配。
服务将大小为1的短期分配分配给一个池中的X个字节,将大小为1的长期分配分配给另一个池中的X个字节。
大小X + 1到2X,2X +1到4X,4X + 1到8X等的分配类似。 (您可以尝试其他桶尺寸......)
要确定X的最佳尺寸,您需要对应用进行配置并查看每个分配尺寸的频率。
确保每个桶有足够的空间来满足分配:)
打趣:切换到垃圾收集。你需要一个压缩垃圾收集器,一个能够物理移动分配的数据,否则它不会帮助分片。
free
和delete
也是非常昂贵的操作。不幸的是,所有这些都是假设的,因为我目前不知道C++的任何压缩增量垃圾回收器。除了C++/CLI。
皮肤有很多种方法让这只猫。但是,你的池分配器是否比默认的'new/delete'更好? – jxh 2013-04-06 08:19:43
实现自己的子分配器的程序员通常最终会做出乌普萨拉朝圣。整理分配大小可能是Q&D修复。 – 2013-04-06 12:22:30
@Clifford,感谢您的更新。 – Saqlain 2013-04-07 16:21:04