將全局操作符new重載爲將所有分配累加到下一個冪的優化有什麼問題嗎?從理論上講,這會降低碎片,但是會導致更高的內存消耗,但是操作系統是否已經具有這種技術的冗餘行爲,還是盡其所能來節省內存?C++中的堆行爲
基本上,考慮到內存使用不像性能那麼重要,我應該這樣做嗎?
將全局操作符new重載爲將所有分配累加到下一個冪的優化有什麼問題嗎?從理論上講,這會降低碎片,但是會導致更高的內存消耗,但是操作系統是否已經具有這種技術的冗餘行爲,還是盡其所能來節省內存?C++中的堆行爲
基本上,考慮到內存使用不像性能那麼重要,我應該這樣做嗎?
默認的內存分配器可能非常聰明,可以很好地處理大量的中小型對象,因爲這是最常見的情況。對於所有分配器,請求的字節數永遠不會總是分配的數量。例如,如果你說:
char * p = new char[3];
分配器幾乎可以肯定不會是這樣的:
char * p = new char[16]; // or some minimum power of 2 block size
除非你能證明你有分配的實際問題,你不應該考慮編寫自己的版本新的。
某些內存分配程序具有不同大小的不同池。對於小的分配,一小塊寬度塊將比大塊池更有效率。 – 2010-06-01 20:15:53
你應該這樣做嗎?第
兩個原因:
總而言之,除非您可以證明(通過分析)它是一個開始的問題,否則不要惹它。不要過早優化。
1)目前還沒有! 2)我不在Windows上。 3)過早優化很有趣。 4)我只是好奇:) – 2010-06-01 21:26:31
你應該嘗試實現它的樂趣。它一運行就扔掉。
我做到了。謝謝! – 2010-06-01 21:32:01
@wowus已經完成?哇,那很快:) – fredoverflow 2010-06-01 21:50:17
我同意Neil,Alienfluid和Fredoverflow在大多數情況下你不想編寫你自己的內存分配器,但我仍然編寫了我自己的內存分配器約15年,並在多年內完善它(第一版本是的malloc /免費重新定義,更高版本中使用全局新/ delete操作符),並在我的經驗,優勢是巨大的:
你提到的每一件事(除了可能的第二點)都可以使用Application Verifier(http://www.microsoft.com/downloads/details.aspx?familyid=c4a25ab9- 649d-4a1b-b4a7-c9d8b095df18&displaylang = en)或UMDH(http://msdn.microsoft.com/en-us/library/ff558947(VS.85).aspx)。 嚴重地說,編寫自己的堆管理器在增加代碼大小,增加安全攻擊面,增加bug等風險方面真的不值得冒險。 – Alienfluid 2010-06-01 20:44:03
我嘗試了所有的Microsoft實用程序(Application Verifier,UMDH,Gflags,.. ),我無法達到與我自己的內存分配器相同的結果。例如,Microsoft工具只能處理內存快照,然後比較兩個快照,而不能像應用程序那樣報告包括調用堆棧在內的應用程序末尾的泄漏。需要考慮的其他因素:我的應用程序可以輕鬆使用500MB內存,最高可達幾GB的內存(在64位env中)。處理內存快照是完全不可能的。 – Patrick 2010-06-01 20:55:40
我正在使用gcc,你所說的是由Valgrind完成的。我認爲這是一個有趣的小項目重載全球新/刪除,但不切實際。因此,我會信任系統分配器。 – 2010-06-01 21:25:18
只是使尺寸成爲2的冪不會強制'new'使用夥伴系統alloc ation,所以你仍然會得到碎片。此外,當'new'分配一個塊時,我認爲它實際上會將負數偏移量的幾個字節分配給您獲得的指針,這取決於調試情況,它會在其中收集自己的信息。順便說一句,夥伴系統在速度和內存方面效率都不是很高。 – 2010-06-01 21:33:09