Fabrice Marguerie是一位软件架构师和咨询师,他在MSDN发表了如何检测和避免.NET程序内存与资源泄漏的文章。此文章描述了编写.NET程序时可能发生的内存与资源泄漏,以及如何避免这些泄漏。

C#这样的编程语言使用垃圾收集器来清理内存,对于程序完全不会再访问的内存,本应是没有内存泄漏的。Fabrice称,内存泄漏发生在一块内存不 再被使用,但却依然被程序所引用时。当一块内存无法被程序访问到时,垃圾收集器将会重新分配这块内存,但是如果程序仍然保持对内存的引用却不使用这块内存 时,就会造成内存泄漏。

Fabrice还列举了一些可能泄漏的系统资源:

  • The system uses User objects to support window management. They include: Accelerator tables, Carets, Cursors, Hooks, Icons, Menus and Windows.
  • 用于窗口管理的用户对象,包括快捷键表、符号、光标、钩子、图标、菜单和窗口。
  • 用于图形的GDI对象:位图、画刷、设备环境(DC)、字体、内存DC、元文件、调色板、画笔、区域等。
  • 用于内存管理、进程执行和进程间通信(IPC)的Kernel对象:文件、进程、线程、信号、定时器、访问令牌、套接字等。

这些资源都是有限制的,注册表中的GDIProcessHandleQuota和 USERProcessHandleQuota键保存了单个进程可用的最大GDI对象和用户对象数量,默认值是10000。虽然这个数字对于大多数程序足 够了,但如果使用的过多则可能会达到另一个限制,一个Windows session最多只能有65536个句柄。Fabrice这个限制很容易就会达到。他的结论是,要小心使用和释放系统资源。

Fabrice列举了一些内存泄漏的根本原因,以及是如何造成泄漏的:

  • 使用静态引用
  • 未退订的事件-作者认为这是最常见的内存泄漏原因
  • 未退订的静态事件
  • 未调用Dispose方法
  • 使用不彻底的Dispose方法
  • 在Windows Forms中对BindingSource的误用
  • 未在WorkItem/CAB上调用Remove

作者在文章中还提供了一些避免内存泄漏的建议:

  • 对象的创建者或拥有者负责销毁对象,而不是使用者
  • 当不再需要一个事件订阅者时退订此事件,为确保安全可以在Dispose方法中退订
  • 当对象不再触发事件时,应该将对象设为null来移除所有的事件订阅者
  • 当模型和视图引用同一个对象时,推荐给视图传递一个此对象的克隆,以防止无法追踪谁在使用哪个对象
  • 对系统资源的访问应该包装在using块中,这将在代码执行后强制执行Dispose

Fabrice最后介绍了一些工具来对付泄漏:GDILeaks(EXE)、dotTrace.NET Memory ProfilerSOS.dllWinDbg

处理.NET中的内存泄露的更多相关文章

  1. 查找并修复Android中的内存泄露—OutOfMemoryError

    [编者按]本文作者为来自南非约翰内斯堡的女程序员 Rebecca Franks,Rebecca 热衷于安卓开发,拥有4年安卓应用开发经验.有点完美主义者,喜爱美食. 本文系国内ITOM管理平台 One ...

  2. 利用Instrument Leak来发现App中的内存泄露

    XCode提供了一组用于检测内存,调试动画,布局等的工具.对于调试一些性能问题,内存问题非常方便.这里我们使用Leak来发现代码中的内存泄露. 在Leak中启动我们的应用开始监控: 注意,在监控的时候 ...

  3. Android内存优化8 内存检测工具2 LeakCanary——直白的展现Android中的内存泄露

    之前碰到的OOM问题,终于很直白的呈现在我的眼前:我尝试了MAT,但是发现不怎么会用.直到今天终于发现了这个新工具: 当我们的App中存在内存泄露时会在通知栏弹出通知: 当点击该通知时,会跳转到具体的 ...

  4. LeakCanary——直白的展现Android中的内存泄露

    之前碰到的OOM问题,终于很直白的呈现在我的眼前:我尝试了MAT,但是发现不怎么会用.直到今天终于发现了这个新工具: 当我们的App中存在内存泄露时会在通知栏弹出通知: 当点击该通知时,会跳转到具体的 ...

  5. Java中的内存泄露 和 JVM GC(垃圾回收机制)

    一.什么是Java中的内存泄露? 在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点, 首先,这些对象是可达的,即在有向图中,存在通路可以与其相连:其次,这些对象是无用的,即程序以 ...

  6. Qt应用中检测内存泄露——VLD

    本文简要描述一下在Qt应用中使用VLD来检测内存泄露.本次测试环境:QtCreator2.3 + Qt4.7.4-vs2008 + VS2008 Express. 1.下载并安装:VLD-2.2: h ...

  7. C++中避免内存泄露常见的解决方式

    常见内存泄露及解决方式-选自ood启发录 new/delete, array new/arrray delete匹配 case 1: 在类的构造函数与析构函数中没有匹配地调用 new/delete! ...

  8. [lua] mac上如何编译snapshot(检测Lua中的内存泄露)

    最近我们的unity手游频繁闪退,只要进入战斗场景,之后一段时间就会闪退,如果是在unity编辑器中则会报出not enough memory的错误!猜测应该是有内存泄漏: 由于我们使用了tolua, ...

  9. Java中的内存泄露的几种可能

    Java内存泄漏引起的原因: 内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏. 长生命周期的对象持有短生命周期对象的引用就很可能发 ...

  10. VS2008中捕获内存泄露(转)

    内存泄露十分讨厌,捕获内存泄露更加令人厌烦…… 其实,VS本身就有内存泄露的检测机制.只需做以下操作即可开启.(同时必须在debug模式 下运行程序并且以 正常流程退出 ) // 在入口函数cpp中添 ...

随机推荐

  1. leetcode problem 42 -- Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  2. 《APUE》第四章笔记(3)

    文件系统 首先我们应该知道一个磁盘可以划分为多个分区,而每个分区就可以包含一个文件系统.UNIX的文件系统是这样的: 而我们主要关心的是i节点和数据块.i节点是固定长度的记录项,它包含有关文件的大部分 ...

  3. position:absolute,绝对定位和相对定位,JQ隐藏和显示

    需要在指定位置,用绝对定位. 如果直接写position:absolute,top:0;left:0,那就是以浏览器的左上角为参照了 现在需要在某一个指定位置用绝对定位 解决方法 在需要用绝对定位(p ...

  4. 简单重置Centos服务器中Mysql的root密码

    1.编辑MySQL配置文件my.cnf vi /etc/my.cnf #编辑文件,找到[mysqld],在下面添加一行skip-grant-tables [mysqld] skip-grant-tab ...

  5. JS 页面打印

    var hkey_root, hkey_path, hkey_key hkey_root = "HKEY_CURRENT_USER" hkey_path = "\\Sof ...

  6. discuz 重新定义jquery的$

    最近做个小插件 发现加了这个代码不执行: $.ajax({ url:'plugin.php?id=register:regeist_jiangsu', type:'post', data:{ 'mob ...

  7. JavaScript自定义方法实现trim()、Ltrim()、Rtrim()

    去除字符串两端的空格,是字符串处理非常常用的方法如何trim() .Ltrim() .Rtrim(),可惜的是javascript中无此方法,下面有个不错的自定义教程感兴趣的朋友可以参考下 去除字符串 ...

  8. c++ union学习

    看到公司前辈的代码中用到了union,不管是大学还是工作用到union机会比较少,还是挺新奇的.所以特意找些资料学习学习 前辈的代码: #include<iostream> using n ...

  9. MFC应用程序的开发流程

    (1)根据应用程序特性在"MFC AppWizard[exe]"应用程序向导各步骤对话框进行选择,创建一个应用程序的框架. (2)利用资源编辑器为程序编辑或添加资源,如编辑菜单.添 ...

  10. LCD显示方向

    一.ILI9341内存到显示地址的映射 本文只讨论“正常显示”,不讨论“垂直滚动显示”模式. 可以看到物理内存被两个指针访问,行指针和列指针,行指针范围从000h到013Fh,列指针范围为0000h到 ...