关于vb.net单元测试的信息

如何在.net应用中发现和避免内存和资源泄露尽管很多人相信在.net应用中谈及内存及资源泄露是件很轻松的事情 。但GC(垃圾回收器)并不是魔法师,并不能把你完全从小心翼翼处理内存与资源损耗中解放出来 。
本文中我将解释缘何内存泄露依然存在以及如何避免其出现 。别担心,本文不涉及GC内部工作机制及其它.net的资源及内存管理等高级特性中 。
理解泄露本身及如何避免其出现很重要,尤其因为它无法轻松地自动检测到 。单元测试在此方面无能为力 。一旦产品中你的程序崩溃了,你需要马上找出解决方案 。所以在一切都还不是太晚前 , 花些时间来学习一下本文吧 。
Table of Content
·介绍
·泄露?资源?指什么?
·如何检测泄露并找到泄露的资源
·常见内存泄露原因
·常见内存泄露原因演示
·如何避免泄露
·相关工具
·结论
·资源
介绍
近期,我参与了一个大的.net项目(暂叫它项目X吧),我在项目中负责追踪内存与资源泄露 。大部分时间我都花在与GUI关联的泄露上 , 更准确地说是一个基于Composite UI Application Block (CAB).的windows窗体应用 。接下来我要说的直接应用到winform上的内容,多数见解同样可以适用到其它.net应用中(像WPF,Silverlight,ASP.NET,Windows service,console application 等等) 。
我不是个处理泄露方面的专家,所以我不得不深入钻研了一下应用程序 , 做一些清理工作 。本文的目标是与你们分享在我解决问题过程中的所得所悟 。希望能够帮助那些需要检测与解决内存、资源泄露问题的朋友 。下面的概述部分首先会介绍什么是泄露,之后会看看如何检测到泄露和被泄露资源,以及如何解决与避免类似泄露,最后我会列出一个对此过程有帮助的工具列表及相关资源 。
泄露?资源?指什么?
内存泄露
在进一步深入前,让我们先来定义下我所谓的“内存泄露” 。简单引用在Wikipedia上找到的定义吧 。该定义与我打算通过本文所帮助解决的问题完美的一致:
在计算机科学领域中,内存泄露是指一种特定的内存损耗,该损耗是由一个计算机程序未成功释放不需要的内存引起的 。通常是程序中的BUG阻碍了不需要内存的释放 。
仍然来自Wikipedia:”以下语言提供了自动的内存管理,但并不能避免内存泄露 。像 Java,C#,VB.NET或是LISP等 。”
GC只回收那些不再使用的内存 。而使用中的内存无法释放 。在.net中,只要有一个引用指向的对象均不会被GC所释放 。
句柄与资源
内存可不是唯一被视为资源的 。当你的.net应用程序在Windows上运行时,消耗着一个完整的系统资源集 。微软定义了系统三类对象:用户(user),图形设备接口(GUI),以及系统内核(kernel) 。我不会在此给出完整的分类对象列表,只是指出一些重要的:
·系统通过使用用户对象(User objects) 来支持windows管理 。相关对象包括:提速缓冲表(Accelerator tables),Carets(补字号?),指针(Cursors),钩子(Hooks),图标(Icons),菜单(Menus)和窗体(Windows) 。
·GDI对象 支持图形绘制:位图(bitmaps),笔刷(Brushes),设备上下文(DC),字体(Fonts),内存设置上下文(Memory DCs),元文件(Metafiles),画笔(Pens),区域(Regions)等 。
·内核对象 支持内存管理,进程执行和进程间通讯(IPC):文件,进程,线程,信号(Semaphores),定时器(Timer),访问记号(Access tokens),套接字(Sockets)等 。
所有系统对象的详细情况都可以在MSDN中找到 。
系统对象之外,你还会碰到句柄(handles).据MSDN的陈述,应用程序不能直接访问对象数据或是对象所代表的系统资源 。取而代之,应用程序一定都会获得一个对象句柄(Handle),可以使用它检查或是修改系统资源 。在.net中无论如何 , 多数情况下系统资源的使用都是透明的,因为系统对象与句柄都由.net类直接或间接代表了 。

推荐阅读