我們不需要死讀硬記,我們需要用基本的知識來發展和增進每個學習者的思考力。——列寧
用c#寫程式的時候,每每一開程式就占用20mb+的記憶體,寫個稍微複雜一點的wpf程式就佔到100+mb。相比之下,用mfc寫的程式占用的記憶體則相當少,20+mb的記憶體占用就比較多了。這點曾讓我相當頭疼,畢竟記憶體占用也是衡量程式質量的乙個比較重要的指標。
在讀了"c# 3.0 in a nutshell"後,終於明白了是怎麼回事。garbage collector並不是每時每刻都在**垃圾的,尤其是對於類似c/c++中的棧型變數,即使在程式控制已經超出這些變數的作用域時,garbage collector也並不立即**空間。這有兩方面的考慮:一方面,既然系統有空餘的物理記憶體,為什麼要犧牲一定效能來花精力來保持乙個較小的記憶體占用呢?讓那些空閒的物理記憶體得到充分利用,為效能的提公升做自己的乙份貢獻豈不很好?從另乙個角度--lazy calculation--的角度來看,選擇性的**當前不再需要的記憶體需要較大的代價,而程式結束後一次性釋放整個程序的記憶體則很簡單。若僅僅當系統真正需要記憶體的時候才進行記憶體**,就能討乙個巧:如果系統記憶體一直很充裕,就一直不需要進行垃圾**,這部分時間就省下來了,程式的效能也就變相上去了。而最壞的情況不過是在執行中系統需要這些記憶體,那時再**也不會有什麼損失,不過是不能討到巧罷了。(lazy calculation的思想在"more effective c++"中也有介紹,在很多程式或系統,包括linux中有重要應用)。
我們可以改動一些c#的程式來驗證clr的確是這樣做的。下面的語句可以得到當前程式真實的記憶體佔用量:
1string
procname
=process.getcurrentprocess().processname;
2using
(performancecounter pc
=new
performancecounter3(
"process",
"private bytes
", procname))
4statustextblock.text
=(pc.nextvalue()
/1000
).tostring();
其中statustextblock.text是狀態列的文字,當然也可以用messagebox等形式輸出。
對於乙個現有的wpf程式做實驗,可以知道在某時刻其真實記憶體佔用量為52mb,而此時用windows xp的task manager觀察則得到它的記憶體占用為100+mb。其中多出的這部分餘量就是已釋放但尚未**的垃圾空間。此時系統的空餘物理記憶體還有60%+,所以garbage collector沒有進行**。而若保持這個程式繼續執行,開啟乙個占用大量記憶體的程式(如visual studio),則可以發現task manager中顯示該程式的記憶體占用變成了52mb+,這是乙個比較理想的結果,說明這個程式真實占用的記憶體不會超過53mb,在某種程度上驗證了上文的理論。也說明c#的大記憶體占用並不是乙個弊病,而是一種合理利用系統資源的手段。這和某些linux愛好者的觀點是一致的:linux記憶體占用比windows xp要大,是合理利用系統資源這一設計意圖的體現而並非bug。(當然,garbage collector對於**垃圾的時機的選擇和很多因素相關,並不僅僅受系統空閒記憶體的影響)
如果看task manager裡面大記憶體占用實在不爽也可以用強制垃圾**的辦法解決。對於上面的程式,如果在統計前呼叫gc.collect();強制**記憶體,在task manager中顯示的記憶體占用就變成了37mb。這個比較詭異,竟然小於程式內部統計得到的數值。根據google的結果,這也許是windows xp下的task manager對clr程式的統計有問題所致,據說在vista下問題有所改善,不過以我的小破本pentium m 1.2g + 768mb ram的條件怕是沒有條件實驗證實了。
當然,即使做了這樣的優化,這個c#占用的記憶體也有50mb左右,和c++程式還是有一定差距,這也許是clr程式執行的原理決定的,其中有.net framework占用的記憶體。這篇文只能指出c#程式的記憶體占用也許沒有windows xp下task manager說的那樣誇張,並提出了一種驗證的方法。至於如何進一步減小c#程式的記憶體占用,也許還需要更精確可靠的記憶體統計手段,更新版本的.net framework和更詳細的c#記憶體分配原理說明。
tag標籤: c#,performance,memory,clr
C 記憶體占用問題
關於學習 完c語言中 變數的記憶體管理和結構 體變數所佔記憶體大小的問題後 到第二階段學 習c 面向對 象的程式設計 大家肯定會有 這樣的疑問 在c 中乙個類對 象究竟占用多少記憶體?最近關於此 問題進行了相關資 料整理,感覺 這裡解釋的 應該很清楚,感 興趣的同學 請網下看 很多c 書籍中都介紹過...
linux記憶體占用問題
linux開機後,使用top命令檢視,4g物理記憶體發現已使用的多大3.2g,佔用率高達80 以上 mem 3889836k total,3341868k used,547968k free,286044k buffers swap 6127608k total,0k used,6127608k f...
C 知識點 記憶體占用問題
有一次去面試,談的挺好的,被人問了乙個問題,瞬間暴露自己基礎能力弱的弱點了,這裡自己記錄下,以後慢慢長進。問題char test1 char test2 char test3 20 這三個語句使用 sizeof 輸出的結果是什麼,而我回答的,全部成了指標的長度了,悲劇啊 qdebug char te...