How to detect and avoid memory and resources leaks in .NET applications 摘译1

原文地址: How to detect and avoid memory and resources leaks in .NET applications

关于内存和资源泄露的说明

1. 提供自动内存管理机制的语言如Java C# VB.Net 并不对内存泄露免疫。

2. 三类主要的易泄露系统对象(system object):
  • 用户对象(User objects): 用于提供窗口管理功能,如快捷键列表,Alt快捷键(Carets),光标,钩子,图标,菜单和窗口。
  • GDI对象: 提供图形功能,如位图、画刷、设备上下文(DC)、字体、Memory DC、Metafiles、调色板、Region等
  • 内核对象:提供内存管理、进程执行、IPC等功能,如文件、进程、线程、信号量、timer、access token、socket等

系统对象本身没有问题,但他们都是有限的,就会出现问题。比如GDI对象的默认上限是10000,但这个值是可以查阅并修改的:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows: GDIProcessHandleQuota and USERProcessHandleQuota.

检测和发现泄漏

三个步骤:
  • 检测泄漏
  • 发现泄漏源
  • 确认在哪里和什么时候泄漏会发生

通常我们不会收到到OutOfMemory,因为当物理内存用尽后,系统会使用磁盘虚拟内存。所以一般会收到"out of handles"异常,具体的异常应该是System.ComponentModel.Win32Exception 或者 System.OutOfMemoryException。而且一般也只会在非常“密集”或长时间的使用程序时才会出现这种情况。

检查泄漏,可以用Memory Profiler工具从root object或者根容器着手,比如LayoutView。下一步就是搞清楚为什么那些没有被释放掉的对象上的引用没有被摘除。

原文作者使用了JetBrains dotTrace进行分析,但也可以使用他所谓的 忍者方法:)

常见的泄露原因

    * 静态引用(static reference)
    * 没有取消订阅的事件(Event with missing unsubscription)
    * 没有取消订阅的静态事件(Static event with missing unsubscription)
    * 没有触发Dispose方法(Dispose method not invoked)
    * Dispose方法没有完成(Incomplete Dispose method)
    * 不合理使用了绑定数据源的WinForm(Windows Forms: BindingSource misused)
    * CAB: missing Remove call on WorkItem

举例说明,在原作者所做的项目中,使用了一个用于管理toolbar的第三方控件,但即便你的toolbar实现了IDisposable接口,控件管理类也不会去调用。幸运的是,可以自己去调用Dispose方法达到目的。
作者强调,虽然framwork也会有泄漏的情况,但那是非常少的情况,所以请大家不要随便推卸责任:)

你可能感兴趣的:(.net,windows,vb,VB.NET,WinForm)