使用.Net Memory Profiler 分析.Net程序內存泄露


.Net 內存泄露無外乎那幾類:
引用未消除,事件未刪除

如果是WPF應用程序,常見的有Image 對象釋放問題,綁定到非依賴屬性或未實現INotifyPropertyChanged 接口的對象屬性.這里不細述.

本文介紹如何使用強大的.Net Memory Profiler 分析.Net 應用程序內存泄露. 使用的Demo 是 使用Mdbg.exe 調試.net 程序 中的Demo.

 

Sample Code:

namespace MemLeakProfileDemo
{

public partial class Form1 : Form
{
private Fool fool;
private FoolBrother brother;

public Form1()
{
InitializeComponent();
fool = new Fool();
brother = new FoolBrother();
//引用fool
brother.YoungFool = fool;
}

private void btnAlloc_Click(object sender, EventArgs e)
{
var i = 10;
//AllocalHugeMem 會申請10M的內存
fool.AllocalHugeMem();
}

private void btnWrongRelease_Click(object sender, EventArgs e)
{
//雖然fool 指向null,但 brother保留了對fool的引用,GC無效果.內存泄露
fool = null;
GCRelease();
}

private void btnRightRelease_Click(object sender, EventArgs e)
{
//消除 brother 對fool的引用,GC效果明顯
fool = null;
brother = null;
GCRelease();
}

private void GCRelease()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}

public class Fool
{
private IList<byte[]> list = new List<byte[]>();

public void AllocalHugeMem()
{
var buffer = new byte[10 * 1024 * 1024];
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = 1;
}
list.Add(buffer);
}
}

public class FoolBrother
{
public Fool YoungFool
{
get;
set;
}
}
}
  • 使用.Net Memory Profiler 啟動 Demo.exe,

 

  • 先抓個快照(Collect Snapshot)
  • 多點擊幾次 Allocal Mem 按鈕,申請內存,再點擊 Wrong Release Mem 按鈕.再抓個快照.

此時:

            //雖然fool 指向null,但 brother保留了對fool的引用,GC無效果.內存泄露
fool = null;
GCRelease();


由於有個 FoolBrother 對象強引用了fool對象,fool對象無法被GC掉. 通過強大的工具,我們可以直觀的看到:

 

mem2

 

有一個Fool 對象instance 未被釋放.雙擊該行查看:

可以看到該對象引用的計數是1,GC 的Age,右邊是創建該對象的堆棧.

雙擊Instances 行.出現清晰的引用關系圖:

mem4

 

一切盡在眼前! 

反之,可以點擊 Right Release Mem 按鈕,將FoolBrother 對象清除,再抓快照,對比效果.

回頭有時間再用此Demo 介紹如何使用Windbg SOS擴展找出內存泄露.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM