6、对象生命周期和垃圾回收基础

掠过架构化异常处理不谈,接下来主要介绍CLR怎样通过垃圾回收来管理已分配的类实例(对象)。C#程序员从来不直接在内存中删除一个托管对象,相反,.net对象被分配到了一块叫做托管堆的内存区域上,到了某个时候他们被垃圾回收期自动销毁。

及时释放内部非托管资源:使用System.Object.Fimalize()虚方法和IDisposable接口。

。net4垃圾回收器的新功能:后台垃圾回收和使用System.Lazy<>泛型实现的延迟实例化。

第一个问题,类、对象和引用。

类是一个蓝图,描述这个类型的实例在内存中看起来是什么样子的。

对象是类的实例,通过new关键字简历的单一的,返回一个指向堆上对象的引用,而不是真正的对象本身。

第二个问题,对象生命周期。

规则,当我们建立一个实例,分配在托管堆上之后,就不用再管。等到一个对象从代码库的任何部分都不可访问的时候,垃圾回收器会从堆中删除它。

要理解,托管队不只是一个由CLR访问的随机内存块。net垃圾回收器是堆的清洁工,它会压缩空的内存块来实现优化(必要的时候)。

注意:

如果我们将对象置为null,编译器会生成CIL代码来确保引用不再指向任何对象,但并不强制垃圾回收器立刻将对象移除,如此,在C#中引用置为null意义就不大了。

准确的说,垃圾回收器使用了两个不同的堆,一个专门用来存储非常大的对象,这个堆在回收周期较少顾忌,因为要重新定位大对象的性能开销很大。尽管如此,认为“托管堆”是一个内存区域一般并没有什么问题。

对象的代:堆上的每个对象都属于下列某代。

第0代:从没有被标记为回收的新分配的对象。

第1代:在上一次垃圾回收中没有被回收的对象。(也就是,它被标记为回收,但因为已经获取了足够的堆空间而没有被删除)

第2代:在一次以上的垃圾回收后仍然没有被回收的对象。

这里的要点是,通过给堆上的对象赋一个表示代的值,尽快地删除一些较新的对象(如本地变量),而不会经常“打扰”一些旧对象(例如程序的应用程序对象)。

第三个问题,System.GC。

基础类库提供了名为System.GC的类类型,它可以通过编程使用一些静态成员与垃圾回收器进行交互。这里要特别注意的是,极少需要在代码中直接使用这个类。一般情况下,只有在创建那些使用非托管资源的类时,才需要使用System.GC的成员。

第四个问题,构建可终结对象(Finalize()虚方法,使用非托管资源时)这种方式速度慢(因为完成一个终结,至少要进行两次垃圾回收)

当为自定义的类重写该方法时,就建立了一个地方,来为类型执行必要的清理逻辑。因为这个成员被定义为保护的,所以不可能通过点操作符从类实力中直接调用一个对象的Finalize()方法。相反,在从内存中删除这个对象之前,垃圾回收器会调用对象的这个方法。

重写System.Object.Finalize()方法:

重写该方法的唯一原因是,C#类通过PInvoke或复杂的COM互操作性任务使用了非托管资源。

始终要记住,Finalize()方法的作用是保证.net对象能在垃圾回收时清除非托管资源。

第五个问题,构建可处置对象。

当垃圾回收生效时,可以利用终结器来释放非托管资源。然而,因为很多非托管资源都是非常宝贵的,所以他们应该尽可能快的被清除,而不能依靠垃圾回收的发生。除了重写Finalize方法之外,类还可以实现IDisposable接口,它定义了一个名为Dispose的方法。

第六个问题,延迟对象实例化。

Lazy<>类的用法,从根本上说,这个新的泛型类可以确保昂贵的对象只在用户需要的时候才会进行分配,这就实现了延迟初始化。

小结:本小节主要介绍对象生命周期和垃圾回收的一些知识,以及最后的延迟对象初始化。从1-6小结,主要都是一些基本的C#编程结构的介绍,接下来,我们将会进行一些高级C#编程结构的陈述和学习。

时间: 2024-10-03 18:16:40

6、对象生命周期和垃圾回收基础的相关文章

JS学习之生命周期与垃圾回收机制

生命周期 变量或者函数在相应的作用域里存在的时间 局部变量和局部函数:不再使用就是生命周期的结束,在函数内声明,当函数执行完毕后,这个变量就不存在了 全局变量和全局函数:当声明完成以后在整个页面中都可以用,当页面关闭的时候生命周期结束 垃圾回收机制: 变量或者函数存在于内存当中,变量在使用完以后,没有在其他地方在使用就会被清除用来释放内存.垃圾回收机制会按照固定的时候周期性的执行 1 function test(){ 2 var n=10; // 在函数内声明,局部变量,在函数外面是访问不到的

.Net组件程序设计之对象生命周期

.Net组件程序设计之对象生命周期 .NET 垃圾回收 IDisposable() Using语句 .NET 垃圾回收 是CLR管理着垃圾回收器,垃圾回收器监控着托管堆,而我们使用的对象以及系统启动是所需要的一些必备的对象信息都存在于托管堆上,CLR会维护着一个列表(对象引用信息列表). 这个列表里存放的信息就是对应着托管堆中所有对象的信息(引用.被引用信息)每当使用一个新的对象或者是改变一个现有对象的引用CLR都会更新 对象引用信息列表.那么回收器一般什么时候调用呢? 垃圾回收器大多数是在托管

[翻译]理解C#对象生命周期

看到网上的一篇讲C#对象生命周期(Object Lifetime)的文章,通俗易懂,而且有图,很适合初学者学习,就翻译过来了.后来发现这是Pro C# 2010 and the .NET 4 Platform的第八章中的一部分.(感谢 大乖乖 提醒).文中的专业名词第一次出现时,括号里会标注对应的英文单词. 请尊重作者劳动,转载请注明出处:http://www.cnblogs.com/Jack47/archive/2012/11/14/2770748.html. ----2012年11月15日修

hibernate session缓存和java对象生命周期

一.java对象生命周期 1.在java中,使用new关键字,创建一个java对象,jvm就为这个对象分配一块内存空间.只要这个变量被引用,他就一直存在于内存中.如果没有被任何变量引用(包括间接引用),那么这个对象就会被垃圾回收器回收.下面用一段代码来解释: Customer c=new Customer(); Order o1=new Order(); Order 02=new Order(); o1.setCustomer(c); c.getOrders().add(o1); o1=null

ASP.NET Core Web API下事件驱动型架构的实现(二):事件处理器中对象生命周期的管理

在上文中,我介绍了事件驱动型架构的一种简单的实现,并演示了一个完整的事件派发.订阅和处理的流程.这种实现太简单了,百十行代码就展示了一个基本工作原理.然而,要将这样的解决方案运用到实际生产环境,还有很长的路要走.今天,我们就研究一下在事件处理器中,对象生命周期的管理问题. 事实上,不仅仅是在事件处理器中,我们需要关心对象的生命周期,在整个ASP.NET Core Web API的应用程序里,我们需要理解并仔细推敲被注册到IoC容器中的服务,它们的生命周期应该是个怎样的情形,这也是服务端应用程序设

struts2.0中Action的对象生命周期详解!!(转)

原文出处:http://blog.csdn.net/wxy_g/article/details/2071662 有很多人问Struts2.0中的对象既然都是线程安全的,都不是单例模式,那么它究竟何时创建,何时销毁呢? 这个和struts2.0中的配置有关,我们来看struts.properties ### if specified, the default object factory can be overridden here ### Note: short-hand notation is

【iOS知识学习】_视图控制对象生命周期-init、viewDidLoad、viewWillAppe

iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 init-初始化程序 viewDidLoad-加载视图 viewWillAppear-UIViewController对象的视图即将加入窗口时调用: viewDidApper-UIViewController对象的视图已经加入到窗口时调用: viewWillDisappear-UIViewCont

_视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途

iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 init-初始化程序 viewDidLoad-加载视图 viewWillAppear-UIViewController对象的视图即将加入窗口时调用: viewDidApper-UIViewController对象的视图已经加入到窗口时调用: viewWillDisappear-UIViewCont

IOS 视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途

iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 init-初始化程序 viewDidLoad-加载视图 viewWillAppear-UIViewController对象的视图即将加入窗口时调用: viewDidApper-UIViewController对象的视图已经加入到窗口时调用: viewWillDisappear-UIViewCont