深入.NET托管堆(managed heap)(下)

原创 2002年05月28日 10:15:00

在这里,对象可以通过两种方式被清除。第一种方式是通过IDisposable接口的Dispose方法。此方法在对象显式地结束时被客户代码调用,它调用InternalDispose(true)。在这种情况下所有的对象都被清除了。如果析构函数被调用,那么InternalDispose(false)被调用,此时只有外部资源会被释放。如果我们已经执行了终止操作,那么我们自己的对象有可能已经被释放了,此后对它们的引用有可能引起异常。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

GC.SuppressFinalize的调用会阻止垃圾收集器将对象放入终止队列中。这样做可以降低在一次GC过程中由于整理对象而引起的内存消耗,并且由于终止操作不会被调用,从而使性能得到提高。

 

C#的优化

 

因此使用IDisposable.Dispose()来释放资源是个很好的方式,它不但可以减少一些在托管堆上进行操作的内存需求,而且能够减少必须执行终止操作的对象的数量。但是它使用起来比较麻烦,尤其是有多个临时对象被创建的时候更是如此。为了能够从IDisposable接口受益,C#客户程序应该书写象下面这样的代码:

 

OverdueBookLocator bookLocator = null;

try

{

    bookLocator = new OverdueBookLocator();

    // Use bookLocator here

    Book book = bookLocator.Find("Eiffel, the Language");

    .

    .

    .

}

finally

{

    if(bookLocator != null)

    {

        IDisposable disp = bookLocator as IDisposable;

        disp.Dispose();

    }

}

 

finally中的代码被用来在有异常发生时作适当的清理工作。为了C#客户程序能够简单有效地使用Dispose模式,Beta2引入了using表达式。Using表达式允许你简化你的代码,因此上面的代码可以写成:

 

 

using(bookLocator = new OverdueBookLocator())

{

   // Use bookLocator here

   Book book = bookLocator.Find("Eiffel, the Language");

}

 

无论何时分配具有明确定义的生存期的类型时,你都应该使用using表达式。它能保证对IDisposable接口的适当调用,即使是在有异常发生的时候。

 

使用System.GC

 

System.GC类用来访问被.NET framework暴露出来的垃圾回收机制。这个类包含以下一些有用的方法:

 

     GC.SuppressFinalize 这个方法在前面已经描述过了,它能够抑制终止操作。如果你已经将属于一个对象的外部资源释放了,调用这个方法来抑制此对象的终止操作的执行。

     GC.Collect 具有两个版本。不带参数的版本在托管堆的所有generation上执行回收动作。另一个版本带有一个整型参数,此参数指明所要进行回收操作的generation。你将很少调用这个方法,因为垃圾收集器在需要的时候会自动调用它。

     GC.GetGeneration 返回作为参数传入的对象所在的generation。这个方法在由于性能的原因而进行的调试和跟踪中很有作用,但是在大部分应用中作用有限。

     GC.GetTotalMemory 返回堆中已经被分配的内存总量。由于托管堆的工作方式,这个数字并不精确,但是如果你以true作为参数的话,还是会得到一个比较接近的近似值。这个方法在计算之前会先执行一遍回收操作。

 

下面是使用这些方法的一个例子:

 

/// <summary>

/// Displays current GC information

/// </summary>

/// <param name="generation">The generation to collect</param>

/// <param name="waitForGC">Run GC before calculating usage?</param>

public void CollectAndAudit(int generation, bool waitForGC)

{

  int myGeneration = GC.GetGeneration(this);

  long totalMemory = GC.GetTotalMemory(waitForGC);

  Console.WriteLine("I am in generation {0}.", myGeneration);

  Console.WriteLine("Memory before collection {0}.", totalMemory);

  GC.Collect(generation);

  Console.WriteLine("Memory after collection {0}.", totalMemory);

}

 

关于本文作者

 

Mickey WilliamsCodev Technologies的创始人之一。Codev Technologies是一家从事位Windows程序开发者提供咨询和工具的机构。他同时也是.NET Experts (http://www.codeguru.com/columns/DotNet/www.dotnetexperts.com)的主要成员,他在此讲授.NET Framework的课程。他时常在美国和欧洲的一些研讨会上发表演讲,并且已经写了八本有关Windows程序设计方面的著作。他目前正被微软出版社邀请写作“Microsoft Visual C#”。你可以在mw@codevtech.com找到他。

Unity内存优化(-)托管堆ManagedHeap的优化

很多童鞋在进行内存分析的时候都会遇到下面的问题: ManagedHeap.UsedSize和ManagedHeap.reservedUnUsedSize这两个占用了很大内存,即使手动GC.Coll...
  • cbbbc
  • cbbbc
  • 2016年04月19日 20:23
  • 4207

.Net 托管代码和非托管代码的区别

什么是托管代码(managed code)?       托管代码是一microsoft的中间语言(IL),他主要的作用是在.NET   FRAMEWORK的公共语言运行库(CLR)执行代码前去...
  • avon520
  • avon520
  • 2014年06月11日 16:47
  • 1297

C#垃圾回收和托管堆及堆栈

堆栈和托管堆: 首先堆栈和堆(托管堆)都在进程的虚拟内存中。(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型。 堆栈实际上是向下填充,即由高内存地址指向低内存地址...
  • lin37985
  • lin37985
  • 2015年06月20日 23:41
  • 734

线程堆栈(Thread Stack)和托管堆(Managed Heap)

内存格局通常分为四个区 全局数据区:存放全局变量,静态数据,常量 代码区:存放所有的程序代码 栈区:存放为运行而分配的局部变量,参数,返回数据,返回地址等, 堆区:即自由存储区       ...
  • xxdddail
  • xxdddail
  • 2014年07月04日 17:23
  • 2045

堆(heap)和栈(stack)有什么区别??

堆栈存放用户自己用malloc分配的空间,用free来释放;由用户自己管理,而栈存放函数的局部变量,由编译器来负责分配和回收管理,速度快,但容量有限, 简单的可以理解为:  heap:是由ma...
  • ly0303521
  • ly0303521
  • 2015年04月09日 19:40
  • 1666

托管堆与堆栈

内存格局通常分为四个区   全局数据区:存放全局变量,静态数据,常量   代码区:存放所有的程序代码   栈区:存放为运行而分配的局部变量,参数,返回数据,返回地址等,   堆区:即自由存储区...
  • Lyncai
  • Lyncai
  • 2013年07月31日 10:42
  • 2101

C# 托管资源 与 非托管资源

C# 托管资源 与 非托管资源托管资源一般是指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,.NET可以自动进行回收,主要是指托管堆上分配的内存资源。例如程序中分配的对象,作用域内的变量等...
  • bingkxin
  • bingkxin
  • 2016年03月17日 11:33
  • 974

数据结构-堆(heap)

堆(heap)也被称为优先队列(priority queue)。队列中允许的操作是先进先出(FIFO),在队尾插入元素,在队头取出元素。而堆也是一样,在堆底插入元素,在堆顶取出元素,但是堆中元素的排列...
  • juanqinyang
  • juanqinyang
  • 2016年05月15日 20:00
  • 1536

数据结构之堆(Heap)及其用途

图、码、文 介绍 优先队列之堆 优先队列;最大树;最大堆、最小堆的插入、删除、初始化; 堆的用途:堆排序;haffman编码;haffman tree 解决优化问题...
  • a1459268562
  • a1459268562
  • 2016年12月07日 18:57
  • 255

c++中堆和栈的的区别(stack vs heap)

 堆和栈的区别 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操...
  • hyqsong
  • hyqsong
  • 2014年12月18日 15:57
  • 2699
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入.NET托管堆(managed heap)(下)
举报原因:
原因补充:

(最多只允许输入30个字)