內存分析一直是個比較令人頭痛的問題,Visual Studio 2013中就集成了一個內存分析的功能,可以方便我們進行分析內存的占用情況。本文將簡單的介紹一下如何使用這個功能。
首先以一個簡單的程序為例:
class MyObj
{
byte[] data;
public MyObj()
{
data = new byte[10240];
}
}
static void Main(string[] args)
{
var buffer = new List<MyObj>();
for (int i = 0; i < 1000; i++)
{
buffer.Add(new MyObj());
}
Console.ReadLine();
}
這個程序比較簡單,啟動的時候申請1000個MyObj對象,每個對象占用10k內存,一共占用10m。
要分析這個程序的內存占用,首先我們需要將其內存dump出來,這里推薦用ProcDump,可以在微軟的網站上下載。使用方式如下:
procdump.exe -ma ConsoleApplication1.exe test.dmp
通過這個命令,就可以將進程當前的內存情況dump出來,生成一個名為test.dmp的dump文件。然后,我們就可以用Visual Studio 2013直接打開這個dump文件了。
點擊右側的"調試托管內"存按鈕開始分析內存,便可以非常清晰的看到內存的占用分布。
另外,它還有一個非常貼心的功能,可以比較兩個dump文件的內存差異:
總體感覺這個功能還是非常好用的,限於篇幅,這里就不做更多的介紹了,要更深入的學習這個功能的話可以看看這篇文章Using Visual Studio 2013 to Diagnose .NET Memory Issues in Production。
不過,有一個問題是,這個功能集成在VisualStudio中了,如果要分析現場遇到的問題時,可能現場的機器中是沒有VisualStudio的,需要把dump文件發送會來分析,但很多時候現場的是沒有通互聯網,或者是一個帶寬較窄的專線的,dump文件又顯得過大而傳輸不便,如果能把這個功能獨立出來就好了。
好在微軟也發布了一個名為ClrMD 單獨的庫可以分析進程和dump文件的內存占用,通過它我們可以寫一個分析程序:
var stats = from o in heap.EnumerateObjects()
let t = heap.GetObjectType(o)
group o by t into g
let size = g.Sum(o => (uint)g.Key.GetSize(o))
orderby size
select new
{
Name = g.Key.Name,
Size = size,
Count = g.Count()
};
foreach (var item in stats)
Console.WriteLine("{0,12:n0} {1,12:n0} {2}", item.Size, item.Count, item.Name);
不過,這個庫還在開發階段,我使用了一下,老報錯,也沒有找到原因。這里就不做過多介紹了,等正式版發布后再單獨寫篇文章體驗下。感興趣的朋友可以看看這篇文章。