zoukankan      html  css  js  c++  java
  • 处理.NET中的内存泄露

    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

  • 相关阅读:
    父子进程 signal 出现 Interrupted system call 问题
    一个测试文章
    《淘宝客户端 for Android》项目实战 html webkit android css3
    Django 中的 ForeignKey ContentType GenericForeignKey 对应的数据库结构
    coreseek 出现段错误和Unigram dictionary load Error 新情况(Gentoo)
    一个 PAM dbus 例子
    漫画统计学 T分数
    解决 paramiko 安装问题 Unable to find vcvarsall.bat
    20141202
    js
  • 原文地址:https://www.cnblogs.com/zeroone/p/3297102.html
Copyright © 2011-2022 走看看