2013-04-06 98 views
2

我從RTOS中分配一個大的內存池(我已經知道我的應用程序內存要求,它不會超過一定的大小)。然後我的應用程序分配請求將從該池中完成。避免內存碎片的方法

最近我開始面臨一個問題;即使內存在那裏(得到集成的內存基準標記框架,顯示了這一點),分配請求並沒有得到滿足,調查顯示我們正在遭受內存碎片化。我的應用程序嚴重依賴於STL(也接收來自網絡的數據,XML解析,圖像處理,將其保存爲PNG等),並作爲內存碎片後面的堆內存分配(是否還有其他原因?),什麼是最好的方法來避免它?

+0

皮膚有很多種方法讓這隻貓。但是,你的池分配器是否比默認的'new/delete'更好? – jxh 2013-04-06 08:19:43

+1

實現自己的子分配器的程序員通常最終會做出烏普薩拉朝聖。整理分配大小可能是Q&D修復。 – 2013-04-06 12:22:30

+0

@Clifford,感謝您的更新。 – Saqlain 2013-04-07 16:21:04

回答

2

內存碎片的典型原因是隨着池老化,大內存塊會被分割成越來越小的塊。避免這種情況的簡單方法是具有固定大小。

這顯然不能解決使用18MB存儲XML的問題,其中每個XML節點存儲爲一個小字符串,然後嘗試加載4096 x 4096 x 8位PNG(16MB),如果您的池是24MB,因爲XML會將你的內存分成很小的一部分,然後你需要16MB的連續內存。但「固定大小」將避免一個XML字符串<aaa>b</aaa>佔用4個字節和2個字節的內存,從而使內存完全無用於存儲在那裏的任何其他對象,因爲沒有其他對象是4或2個字節長。

該方法將要求您的內存分配器正在寫入以考慮「固定大小」。

+0

我同意。將您的游泳池分成多個桶,每個桶只分發固定大小的塊。 – 2013-04-06 08:28:34

2

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

如果不是,請查看是否有其他人已經實施了低碎片分配器。 A related question(來自右側欄)提供了一個示例。

第三,如果沒有其他現有的解決方案工作,解決方案將是使用多個內存池進行分配。

服務將大小爲1的短期分配分配給一個池中的X個字節,將大小爲1的長期分配分配給另一個池中的X個字節。

大小X + 1到2X,2X +1到4X,4X + 1到8X等的分配類似。 (您可以嘗試其他桶尺寸......)

要確定X的最佳尺寸,您需要對應用進行配置並查看每個分配尺寸的頻率。

確保每個桶有足夠的空間來滿足分配:)

0

打趣:切換到垃圾收集。你需要一個壓縮垃圾收集器,一個能夠物理移動分配的數據,否則它不會幫助分片。

  • 垃圾收集不一定與實時要求不兼容。實時意味着「您的系統必須在一定的期限內保證反應」。如果垃圾收集器逐漸工作,並且可以保證足夠短的「持有世界」階段,那麼你就很好。
  • 現代垃圾收集器的表現並不全是壞事。人們總是會忘記freedelete也是非常昂貴的操作。
  • 有垃圾收集的權衡:最有效的是長期持有的世界階段。世界短暫階段的整體效率較低。

不幸的是,所有這些都是假設的,因爲我目前不知道C++的任何壓縮增量垃圾回收器。除了C++/CLI。