C#佔用記憶體的問題

來源:互聯網
上載者:User

用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的確是這樣做的。下面的語句可以得到當前程式真實的記憶體佔用量:

1 string procName = Process.GetCurrentProcess().ProcessName;
2 using (PerformanceCounter pc = new PerformanceCounter
3 ("Process", "Private Bytes", procName))
4 statusTextBlock.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#記憶體配置原理說明。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.