控件中国网现已改版,您看到的是老版本网站的镜像,系统正在为您跳转到新网站首页,请稍候.......
中国最专业的商业控件资讯网产品咨询电话:023-67870900 023-67871946
产品咨询EMAIL:SALES@COMPONENTCN.COM

.NET框架下如何使用自动内存管理

作者:不详 出处:IT专家网 2010年02月03日 阅读:

C#使用的自动内存管理,使用开发者从繁重的手工分配、释放内存的操作解放出来。内存的自动管理是由垃圾回收器来执行。一个对象使用内存的生命周期是这样的:当对象被创建时,它便分配了一定的内存,当构造器中的代码开始运行时,这个对象就“活”了。

  当这个对象或者是它的任何一部分在可以预计的将来已经没有任何作用时,这个对象将不会再使用,它就应当被销毁。

  一旦这个对象符合了对销毁的条件,在一定的时间后,这个对象的销毁器就将被执行,一般情况下,除非被显示地重写,这个销毁器只能运行一次。

  一旦销毁器被运行,那么这个对象以及它任何一部分都不可能在以后的运行中使用,这甚至包括正在运行的销毁器。这时这个对象将被认为是不可见的,它所占的资源将会被回收。

  最后由垃圾回收器释放这个对象所占的资源。

  垃圾回收器控制着这些对象的使用信息并利用这些信息控制内存,比如内存哪里创建了一个新对象,什么时候重新创建对象以及什么时候将这个对象释放。

  像其它的语言一样,C#假定确实存在这样一个垃圾回收器,而且这个垃圾回收器可以管理很大范围的内存。比如,C#并不要求销毁器一事实上要执行,也不要求对象一旦无用则马上回收。

  当然垃圾回收器的行为也是可以被控制的,这个控制的方法来自于System.GC类。这个类可以请求回收、销毁器运行等操作。

  下面是一个例子。

  class A

 {
  ~A() {
  Console.WriteLine("Destruct instance of A");
  }
  }
  class B
  {
  object ref;
  public B(object o) {
  ref = o;
  }
  ~B() {
  Console.WriteLine("Destruct instance of B");
  }
  }
  class TMest
  {
  static void Main() {
  B b = new B(new A());
  b = null;
  GC.Collect();
  GC.WaitForPendingFinalizers();
  }
  }

  上面的程序创建了类A与类B的一个实例,当变量b被赋于null值时,A与B均符合了垃圾回收器的回收要求。此时就没有任何代码能够访问它们了。

  执行的结果,下面两种情况都有可能:

  Destruct instance of A

  Destruct instance of B

  与

  Destruct instance of B

  Destruct instance of A

  因为上面的程序的并没有限制这两个对象被回收的顺序。

  在某些敏感的条件下,有关区分“销毁”与“回收”操作条件的定义是非常重要的:

  class A

 {
  ~A() {
  Console.WriteLine("Destruct instance of A");
  }
  public void F() {
  Console.WriteLine("A.F");
  TMest.RefA = this;
  }
  }
  class B
  {
  public A Ref;
  ~B() {
  Console.WriteLine("Destruct instance of B");
  Ref.F();
  }
  }
  class TMest
  {
  public static A RefA;
  public static B RefB;
  static void Main() {
  RefB = new B();
  RefA = new A();
  RefB.Ref = RefA;
  RefB = null;
  RefA = null;
  // A and B now eligible for destruction
  GC.Collect();
  GC.WaitForPendingFinalizers();
  // B now eligible for collection, but A is not
  if (RefA != null)
  Console.WriteLine("RefA is not null");
  }
  }

  在上面的程序中,如果垃圾回收器选择先执行类B的销毁器,那么执行的结果为:

  Destruct instance of A

  Destruct instance of B

  A.F

  RefA is not null

  注意,虽然实例A并没有被使用,但是从输出的结果大家可以看到A的销毁器确实执行了,而且连A的方法F也被执行了。同时我们也注意至,一个对象销毁器的运行又可能使一个实例变得可用。在这种情况下,实例B销毁器的执行使得先前并没有调用的实例A也可以被访问了,而这一种就是引用RefA的功劳,当调用WaitForPendingFinalizers方法以后,实例B就可以被垃圾回收器回收,而此时的实例A则还不可以。

  为了区分这些行为,大家编写程序时,最好只管理当前类的销毁器,而不要采用引用其它类的实例或者静态字段。

热推产品

  • ActiveReport... 强大的.NET报表设计、浏览、打印、转换控件,可以同时用于WindowsForms谀坔攀戀Forms平台下......
  • AnyChart AnyChart使你可以创建出绚丽的交互式的Flash和HTML5的图表和仪表控件。可以用于仪表盘的创......
首页 | 新闻中心 | 产品中心 | 技术文档 | 友情连接 | 关于磐岩 | 技术支持中心 | 联系我们 | 帮助中心 Copyright-2006 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 电话:023 - 67870900 传真:023 - 67870270 产品咨询:sales@componentcn.com 渝ICP备12000264号 法律顾问:元炳律师事务所 重庆市江北区塔坪36号维丰创意绿苑A座28-5 邮编:400020
在线客服
在线客服系统
在线客服
在线客服系统