FastMM相關

1.使用了FullDebugMod後,不顯示行號?

  要顯示行號需要在delphi中勾上"Debug Information","Reference Info" "Use Debug DCUs"

2.使用borlndmm.dll替換了IDE自帶的以後,雙開IDE然後關閉其中一個時會報錯

  編譯DLL時要設置“NeverUninstall”

3.使用了FullDebugMode後,報$808080xxx訪問違例的錯誤

  通常是使用指針訪問了已經釋放的內存,FastMM會將已經釋放的內存使用$80填充

4.使用了FastMM的內存泄漏檢測會使應用程序運行變慢嗎?

  不會,內存泄漏檢測是在應用程序關閉時進行的


默認情況下FastMM調用棧的追蹤深度是11,有時候可能不夠用,可以在FastMM.pas中修改StackTraceDepth的值(注意註釋:修改的值需要是奇數)


== FastMM技術細節

FastMM實際上是一個3合1的內存管理,分別是小塊(<2.5k)、中塊(<260k)、大塊(>260)內存管理器,他們是獨立管理的。


大塊內存是從地址空間的高地址開始分配,中小塊內存是從低地址開始分配的,大塊和中小塊分開處理可以減少內存碎片的產生。

(↑經測試,在FullDebugMode時都是從高地址開始分配)


中塊內存管理器從操作系統以1.25M的大小獲取內存塊,這種內存塊被叫做“中塊池”,因爲在應用程序申請內存時這種內存塊會

再被細分爲中塊。沒有使用的中塊被串在雙向鏈表裏,一共有1024個這樣的鏈表,而且由於中塊的粒度是256byte,這就意味着

對每個申請的可能大小的內存塊都有對應一個虛擬的容器。FastMM維護着爲這些鏈表維護着一個兩級的位圖,所以要找到一個

合適大小且空閒的內存塊並不需要挨個探查。當一個釋放一箇中塊的時候,FastMM會檢查和它相鄰的塊,如果相鄰的塊未使用,

FastMM就將它和剛剛釋放的塊合併,所以永遠不可能有兩個相鄰的未用的塊。

FastMM沒有內存清理線程,要釋放內存,必須手動調用FreeMem之類的函數。


在類似delphi這樣的面向對象的語言,通常情況下內存的分配和釋放都是小對象。在實測了大量delphi編寫的程序後,平均下來,

超過99%的內存操作涉及的塊都需要2k,因此針對這樣的小塊內存做優化很有必要。小塊是從“小塊池”分配的。小塊池實際上就是

被分成很多等大小塊的中塊內存。

因此小塊池只包含等大小的塊,並且相鄰的未用小塊永遠都不會合並,FastMM爲每種大小的小塊池維護一個雙向鏈表,所以查找

指定大小的小塊會非常迅速。


在內存中到處移動數據是典型的耗資源操作。因此,FastMM實現了一個非常只能的重分配算法,來儘量避免內存移動操作。

當需要擴大一塊內存時,FastMM會將其擴大到以後可能會使用的大小,也就是會多擴展一些,以便下次擴展時不需要重新分配內存。

同樣,當需要縮小一塊內存時,除非FastMM明確地知道剛剛被裁減的內存不會再次被分配回去,否則這塊內存不會被移除。


FastMM通過優化鎖機制來進一步提升速度:小塊,中塊,大塊內存是獨立加鎖的。調用GetMem時,如果最合適的塊的類型被其他

線程鎖住了的話,那麼FastMM會向上嘗試更大的塊,這種設計大大減少了線程爭奪資源的機率,提高了多線程應用程序的性能。
















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章