避免内存碎片的方法
Ways to avoid memory fragmentation
我从RTOS分配了一个大内存池(我已经知道我的应用程序内存需求,它不会超过一定的大小)。然后我的应用程序分配请求从该池中得到满足。
最近我开始面临一个问题;即使有内存,分配请求也没有得到满足(集成内存基准测试框架显示了这一点),调查显示我们正在遭受内存碎片的困扰。
我的应用程序严重依赖STL(也从网络接收数据,XML解析,图像处理,将其保存为PNG等),以及内存碎片背后的堆内存分配(还有其他原因吗?),什么是避免它的最佳方法?
内存碎片的典型原因是,随着池的老化,大的内存块被分割成越来越小的块。避免这种情况的简单方法是设置固定的大小。
这显然不能解决使用18MB存储XML的问题,其中每个XML节点存储为一个小字符串,然后尝试加载4096 x 4096 x 8位PNG (16MB),如果您的池是24MB,因为XML将内存分割成小位,然后您需要16MB的连续内存。但是"固定大小"将避免<aaa>b</aaa>
的XML字符串占用4字节和2字节的内存,从而使内存对存储在那里的任何其他对象完全无用,因为没有其他对象是4或2字节长。
此方法将要求您的内存分配器在写入时考虑"固定大小"。
第一步是看看RTOS是否为低碎片堆提供了任何机制。
如果没有,请查看其他人是否已经实现了低碎片分配器。一个相关的问题(来自右侧栏)提供了一个示例。
第三,如果没有其他现有的解决方案,一个解决方案是使用多个内存池进行分配。
服务从一个池中短时分配大小为1到X字节,从另一个池中长时间分配大小为1到X字节。
对于大小为X +1到2X、2X +1到4X、4X +1到8X等的分配也是如此。(你可以尝试其他桶的大小…)
为了确定X的最佳大小,你需要分析你的应用程序并查看每个分配大小的频率。
确保每个bucket都有足够的空间来完成分配:)
假设:切换到垃圾收集。您需要一个压缩垃圾收集器,它能够在物理上移动已分配的数据,否则它将无法帮助处理碎片。
- 垃圾收集不一定与实时需求不兼容。实时意味着"你的系统必须保证在一定期限内做出反应"。如果垃圾收集器以增量方式工作,并且能够保证足够短的"空出世界"阶段,那么就可以了。
- 现代垃圾收集器的性能并不都很差。人们总是倾向于忘记
free
和delete
也是非常昂贵的操作。 垃圾收集是有权衡的:最有效的垃圾收集具有较长的空世界阶段。空相较短的总效率较低。
不幸的是,所有这些都是假设的,因为我目前还不知道有任何针对c++的压缩、增量垃圾收集器。除了c++/CLI。
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 在嵌入式系统中读取文件的内存碎片
- 内存碎片会减慢新/malloc
- 最终的ARM Linux内存碎片与NEON Copy,但不是memcpy
- 内存碎片是否导致内存异常
- 是否有可能解决 CUDA 内存碎片问题
- 重新分配内存以避免内存碎片
- C++:这看起来像内存碎片吗
- 防止多态容器中的内存碎片
- 堆分离以解决内存碎片
- C++中的内存碎片
- 内存碎片整理在64位系统上仍然相关吗
- 虚拟方法内存使用Java与C++
- 大量的页面错误与内存碎片有任何关系
- 我应该担心std::vector的内存碎片吗?
- 避免内存碎片的方法
- 多线程是否强调内存碎片
- c++纯虚拟方法内存管理问题