你知道.NET框架下的自动内存管理吗?

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

  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则还不可以。

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

目录
相关文章
|
16天前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
|
2月前
|
开发框架 JavaScript 前端开发
5个.NET开源且强大的快速开发框架(帮助你提高生产效率)
5个.NET开源且强大的快速开发框架(帮助你提高生产效率)
|
4月前
|
开发框架 缓存 Cloud Native
微软发布 .NET 云原生开发框架—— .NET Aspire
微软于 2023-11-14日 发布了 .NET 8 的正式版。伴随着这个重要 .NET 版本的发布,微软也发布了一个全新的 .NET云原生开发框架 —— .NET Aspire,它提供了如下 3 个方面的能力,来帮助我们使用 .NET 开发分层、云就绪的可观测、本地与生产环境一致的分布式云原生应用程序。
199 0
|
1月前
|
开发框架 网络协议 .NET
深入.net框架
深入.net框架
11 0
|
2月前
|
算法 BI API
C#/.NET/.NET Core优秀项目和框架2024年1月简报
C#/.NET/.NET Core优秀项目和框架2024年1月简报
|
3月前
|
PHP Windows
php扩展com_dndnet(PHP与.NET框架进行交互)
php扩展com_dndnet(PHP与.NET框架进行交互)
php扩展com_dndnet(PHP与.NET框架进行交互)
|
3月前
|
开发框架 前端开发 JavaScript
一款基于.NET Core的快速开发框架、支持多种前端UI、内置代码生成器
一款基于.NET Core的快速开发框架、支持多种前端UI、内置代码生成器
100 0
|
3月前
|
SQL JavaScript NoSQL
3个.NET开源简单易用的任务调度框架
3个.NET开源简单易用的任务调度框架
110 0
|
3月前
|
数据采集 开发框架 JavaScript
C#/.NET/.NET Core优秀项目和框架2023年12月简报
C#/.NET/.NET Core优秀项目和框架2023年12月简报
|
4月前
|
C# Android开发 iOS开发
9 个 .NET UI 框架,您的选择是?
介绍 9 款 .NET UI 框架,有你的菜麽。
205 1
9 个 .NET UI 框架,您的选择是?