2011-10-31 99 views
5

我應該擔心std :: vector的內存碎片嗎?如果是這樣,有什麼方法可以幫助阻止它?我並不總是預測我的程序會在PC上運行,它們也可能在嵌入式設備/遊戲控制檯上運行,所以我不會總是能夠依靠虛擬內存。我應該擔心與std :: vector的內存碎片?

然後我再次相信,使用動態大小的數組而不是靜態數組會更高效,因此只有在需要時纔會分配內存。它也會簡化我的程序的設計過程。有沒有辦法有效實現這一點?

感謝您的任何建議!

+1

有一個可選的allocator模板參數,您可以指定該參數以更加嚴格地控制內存分配的方式。 –

回答

10

您的疑慮的答案可能是std::deque。它給你提供了一個與std::vector類似的接口,但是對於分段內存來說效果更好,因爲它分配了幾個小數組而不是一個大數組。它在某些方面實際上效率低於std::vector,但對您而言,這可能是一個很好的折衷。

+0

您可以爲您提出的聲明提供網站來源嗎?最好是標準參考? **更新**自己找到了一個開始:http://www.gotw.ca/gotw/054.htm – sehe

+1

@sehe:恐怕標準往往不會強制執行以允許未知的優化。它甚至不強制使用內部數組來實現'std :: vector',但我非常懷疑任何人都可以實現它。但通常'std :: deque'是使用小型數組實現的。例如,參見http://www.cplusplus.com/reference/stl/deque/,以進行一個簡短的獨立於圖書館的討論。 – Gorpik

1

不,std :: vector保證連續存儲。你可以使用vector :: reserve()來避免隨着矢量大小的增加重新分配。

+3

這正是您爲什麼需要擔心內存碎片的原因。如果新找不到,例如。一個備用的4k連續塊,它不能分配1000個整數的向量。 –

+1

這甚至與堆碎片有關嗎?堆碎片不依賴於類的佈局。它取決於分配模式和分配策略/算法。 – sehe

+0

我擔心內存碎片意味着'擔心被訪問的內存被碎片化',因爲訪問非連續內存意味着你可能沒有從預取等方面獲得性能優勢。 – bames53

2

你應該總是擔心性能和效率當你的分析器告訴你,(可以是探查,但你必須「措施」,而不是猜測)。

事情可以做:

  1. 預分配容量:

    std::vector<int> x(1000); // size() is 1000 
    
    std::vector<int> y; 
    y.reserve(1000); // size() is 0, capacity is 1000 
    
  2. 使用自定義分配器

第一種選擇顯然是速贏;第二種選擇更多,我只在你的堆分析器告訴你碎片導致問題時才推薦它。

對於堆紋,我建議

3

的std ::矢量只是像新的一樣好。它只是爲你處理底層內存分配問題 你可以做幾件事 - 假設你不想寫一個全新的新的處理程序。

預先分配矢量或調整大小(),如果你知道它們將會是什麼樣的大小,這樣可以避免浪費的內存副本。

如果您要再次使用具有相同大小的矢量,最好保留它並重新填充,而不是刪除它並重新創建它。

通常在嵌入式目標中,如果您知道內存需求,最好在開始時靜態分配所有內存並自行分配 - 這不像另一個用戶需要一些內存。

5

如果您的向量將被重新分配多次然後是的,它可能會導致內存碎片。 如果您或多或少知道陣列可以發展的規模,最簡單的方法就是使用std::vector::reserve()

你也可以考慮使用std::deque來代替矢量,所以你根本就不會有內存碎片的問題。

這是關於可能會讓你感興趣的stackoverflow的主題:what-is-memory-fragmentation

2

的一個好方法,以儘量減少重複內存分配和再分配調用與std::vector是自由使用的std::vector::reserve()如果你有多少個元素的矢量將使用一些想法。這將預先分配容量並防止在您通過push_back()添加元素時矢量所維護的內部數組的大小調整。