2008-09-23 38 views
4

假設您在C/C++中有相當大的(〜2.2 MLOC)Windows相當老的(從10多年前開始的)Windows桌面應用程序。大約10%的模塊是外部的,沒有源代碼,只有調試符號。減少大型陌生代碼庫的內存佔用面積

你會如何將應用程序的內存佔用減少一半?至少,你會怎麼做才能找出內存消耗的位置?

回答

0

我不認爲你的問題是好的。

源代碼的大小與內存佔用不直接相關。當然,編譯後的代碼會佔用一些內存,但是應用程序可能會自己擁有內存需求。靜態(在代碼中聲明的變量)和動態(應用程序創建的對象)。

我建議你簡介程序執行並仔細研究代碼。

+0

源代碼提示的大小,在項目的整體複雜性。您認爲需要多長時間「仔細研究」400 KLOC? :) – Constantin 2008-09-23 19:01:56

+0

它應該很容易。 400k不是我所謂的大:)因爲你只需要檢查堆分配,找到所有的malloc和新的調用,你幾乎在那裏。 – gbjbaanb 2008-09-23 19:06:57

+0

gbjbaanb,我希望我可以告訴你*只是*模塊依賴關係圖:)和有關「找到所有的malloc和新的」,還有至少SysAllocString(經常埋在CComBSTRs內) – Constantin 2008-09-23 19:45:05

2

這不是一件容易的事。首先追查你找到的任何內存泄漏(一個好的工具是Rational Purify)。瀏覽源代碼並嘗試優化數據結構和/或算法。
對不起,如果這聽起來很悲觀,但是將內存使用量減少50%聽起來不太現實。

7

使用包裝函數覆蓋malloc()/ free()和new()/ delete(),它們跟蹤分配的大小和(通過記錄調用堆棧並稍後在符號表中進行解析)從。關閉時,讓包裝顯示仍分配的內存。

這應該使您能夠計算出最大分配的位置並捕獲任何泄漏。

+0

您可以詳細說明覆蓋分配函數的最佳方法應用程序範圍內,最好是有限的源代碼更改?另外,還有很多COM/BSTR處理;我相信他們的分配者不能被排除在分析之外。 – Constantin 2008-09-23 19:39:20

3

this is description/skeleton內存跟蹤應用程序我用來減少我們遊戲的內存消耗20%。它幫助我追蹤由外部模塊完成的許多分配。

0

一是地方開始對我來說將是:

應用程序做了很多預分配內存以供以後使用?這種記憶是否經常坐在未使用的地方,從未分發過?考慮根據需要切換到新建/刪除(或更好地使用smart_ptr)。

是否代碼使用作爲

Object arrayOfObjs[MAX_THAT_WILL_EVER_BE_USED]; 

一個靜態數組,例如,該陣列中分發的OBJ?如果是這樣,請考慮手動管理此內存。

1

有一個機會是你可以非常快地發現一些顯着的低效率。首先,你應該檢查什麼是內存使用。我發現一個非常方便的工具是Memory Validator

一旦你有這個「內存使用情況地圖」,你可以檢查低掛水果。是否有任何數據結構消耗大量內存,可以用更緊湊的形式表示?這通常是可能的,尤其是,當數據訪問得到很好的封裝,並且當你有一個可用的CPU電源時,你可以專門在每次訪問時對它們進行壓縮/解壓縮。

0

內存使用分析工具之一是LeakDiag,可用於free download from Microsoft。它顯然允許將所有用戶模式分配器掛接到VirtualAlloc,並隨時將進程分配快照轉儲爲XML。這些快照可用於確定哪些調用堆棧分配大部分內存以及哪些調用堆棧正在泄漏。它缺乏用於快照分析的漂亮前端(除非通過Microsoft Premier支持獲得LDParser/LDGrapher),但所有數據都在那裏。需要注意的

一件事是,你可能有從BSTR分配假陽性泄漏由於緩存,看"Hey, why am I leaking all my BSTR's?"