本文由DevDiv Vincent(vincent@devdiv.com)意译,转载请注明出处!
原文:
http://blogs.windows.com/windows_pho...rformance.aspx

内存泄露无处不在,无论是Native Code还是托管代码。
本文将通过一个示例展示如何使用Profiler工具定位Windows Phone程序中的内存泄露。

Part1. 示例介绍:
我们构建一个简单的应用程序,此程序一共包含两个页面。
Page1中有两个按钮,一个用来跳转到Page2,另一个用来强制GC回收;
Page2中用来显示4张图片,构造函数中添加对Touch支持。
由于代码很简单,我们不一行行介绍,让我们来看看Page2的构造函数:
[代码]c#/cpp/oc代码:
Code:
public Page2()
{
    InitializeComponent();
    var streaminfo = App.GetResourceStream(new Uri("/managedleak;component/hydrangeas.jpg", UriKind.Relative));
    var bitmap = new BitmapImage();
    bitmap.SetSource(streaminfo.Stream);
    image.Source = bitmap;
    streaminfo = App.GetResourceStream(new Uri("/managedleak;component/hydrangeas2.jpg", UriKind.Relative));
    bitmap = new BitmapImage();
    bitmap.SetSource(streaminfo.Stream);
    image2.Source = bitmap;
    streaminfo = App.GetResourceStream(new Uri("/managedleak;component/hydrangeas3.jpg", UriKind.Relative));
    bitmap = new BitmapImage();
    bitmap.SetSource(streaminfo.Stream);
    image3.Source = bitmap;
    streaminfo = App.GetResourceStream(new Uri("/managedleak;component/hydrangeas4.jpg", UriKind.Relative));
    bitmap = new BitmapImage();
    bitmap.SetSource(streaminfo.Stream);
    image4.Source = bitmap;
    Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
}
构造函数中除了设置图片外,另外设置了Touch的处理函数。
我们来看一下程序的截图



Part2. 演示内存泄露:
Windows Phone中可以利用Profiler工具检测内存泄露,具体步骤如下:
Invoke the Profiler, choose “Memory (managed object allocation and texture usage)”, and launch the application. Note the memory used by the application at the top of the screen.(Debug菜单下选择Start Windows Phone Application Analysis)
Click on Go To Page2. This will launch Page2, and display the 4 flower images.
Click on the back button.
Click on ‘Force GC’. Note the memory used by the application at the top of the screen. Observe that it does not go down.
Repeat steps 2, 3, 4 four more times.
Now click on ‘Stop Profiling’.
停止Profiler后可以看到如下效果

大家可以看出内存在不断增长。
Part3内存泄露分析:
我们可以用鼠标选中曲线的一段,点击“开始分析”,分析完成!
你会发现内存中有若干个Page2的示例存在

进一步分析Page2,点击其中一个示例,然后看“GC根”,你会发现Page2占用内存的地方只有两处,一个是Grid为根的界面,一个是event handler。

我们的界面很简单,所以我们重点放在这个event handler上。
再查看Page2.xaml.cs可以看出,我们调用了
Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
但却没有任何一处调用
Touch.FrameReported -= new TouchFrameEventHandler(Touch_FrameReported);
这个就是内存泄露的地方,
因为Touch是全局的,所以它不会释放,那么TouchFrameEventHandler就不会释放,而TouchFrameEventHandler是Page2的成员,TouchFrameEventHandler不释放,那么Page2就不能释放。

代码下载:
由于小弟在此没有上传附件权限,代码请这里下载:
http://www.devdiv.com/windows_phone_-blog-1-51975.html