1. 概述

  本章内容包括 管理非托管资源、使用IDisposable接口 以及 管理析构器和垃圾回收。

2. 主要内容

  2.1 理解垃圾回收机制

    ① 代码执行的时候,内存中有两个地方存放数据项:堆 和 栈。

    ② 一个方法结束的时候,其使用的栈空间会被自动清空。 而堆空间,是由垃圾回收器管理的。

    ③ 垃圾回收器的工作原理是:启动以后,垃圾回收器的标记程序会遍历堆上保存的对象,标记出仍然被引用的对象,然后压缩程序启动,它会把当前仍然存在引用的对象移动到一起,然后释放掉其他不存在引用的对象。

    ④ 执行垃圾回收期间,为了确保对象状态的准确性,系统会暂停其他所有线程的执行,直到垃圾回收执行完毕。这可能会导致一定的程序响应问题。

    ⑤ 为了解决上述问题,垃圾回收器被设计成智能的。它会尽量在堆空间不足或内存不足的时候启动,而且尽量会在程序使用率低的时候启动。

    ⑥ 执行标记程序的时候,首次遍历到的对象默认是Generation 0,如果检测到该对象存在引用,则会提高该对象的Generation。其中根据的原则是:长时间停留的对象,可能会停留较长时间。所以这些对象仅会在空间不足的时候才会去检测和释放。

  2.2 管理非托管资源

    不涉及非托管资源的时候,基本无需考虑内存及资源管理问题,垃圾回收器都能处理好。但是一旦涉及到非托管资源,垃圾回收器就无能为力了,这时候就需要手动释放资源。

    析构器(finalizer)是释放资源的一种方式,但是C#中,析构器的执行时间是不确定的,是由垃圾回收器的算法决定的。但是可以通过调用GC.Collect来强制执行析构器。(这种做法是不推荐的)

StreamWriter sw = File.CreateFile("temp.dat");
sw.Write("some data");
GC.Collect();
GC.WaitForPendingFinalizers();
File.Delete("temp.dat");

   析构器延长了对象的生命周期。因为析构器总要执行,.net平台会在一个特殊的析构队列中保存一个该对象的引用。这会推迟垃圾回收器的回收时间。

    综上所述,对于释放非托管资源,析构器不是一个很好的方案。.net有更好的推荐:IDisposable。

using(StreamWriter stream = File.CreateText(“temp.dat”))
{
  stream.Write(“some data”);
  stream.Dispose();
  File.Delete(“temp.dat”);
}

    使用using,可以自动处理其中代码的异常情况,避免因为代码中的异常可能导致的资源没有释放的问题。

  2.3 实现IDisposable接口和析构器

    在自定义类型中同时实现IDisposable接口和析构器,是一个必要的方案。可以避免用户忘记调用Dispose方法的情况。

class UnmanagedWrapper : IDisposable
{
public FileStream Stream { get; private set;} public UnmananagedWrapper()
{
this.Stream = File.Open("temp.dat", FileMode.Create);
} ~UnmanagedWrapper()
{
Dispose(false);
} public void Close()
{
Dispose();
} public void Dispose()
{
Dispose(true);
System.GC.SuppressFinalizer(this);
} public void Dispose(bool disposing)
{
if (disposing)
{
if (Stream != null)
Stream.Close();
}
}
}

    * System.GC.SuppressFinalizer(object obj)会请求系统不要调用指定对象的析构器。

  2.4 弱引用(weak references)

static WeakReference data;
public static void Run()
{
object result = GetData();
//GC.Collect(); 取消这行注释将会导致data.Target为null
result = getData();
}
private static object GetData()
{
if (data == null)
data = new WeakReference(LoadLargeList()); if (data.Target == null)
data.Target = LoadLargeList(); return data.Garget;
}

   弱引用可用于缓存场景,用弱引用定义的对象,不会阻碍垃圾回收器的回收。上面的GetData方法,确保在对象被回收以后,重新获取并保存对象。

3. 总结

  ① C#中,用堆和栈在内存中保存数据项。堆空间是受垃圾回收器管理的。

  ② 垃圾回收器会释放堆上那些已经不存在引用的对象。

  ③ 析构器是类中一段特殊的代码,在类对象被删除的时候,由垃圾回收器负责调用。

  ④ IDisposable接口,可以实现用可控的方式来释放非托管资源。

  ⑤ 可以用using关键字来确保实现了IDisposable的对象总会被成功释放。

  ⑥ 弱引用 可以保存一个对象,该对象会被垃圾回收器当做已经没有引用的对象而回收。

第十一章 管理类型(In .net4.5) 之 管理对象的生命周期的更多相关文章

  1. 第十二章 管理类型(In .net4.5) 之 操作字符串

    1. 概述 本章包括 字符串基本操作 以及 查找.遍历.格式化字符串. 2. 主要内容 2.1 在.net平台中使用字符串 C#中,string是用来保存文本信息的.是一个被当做值类型使用的引用类型. ...

  2. 第七章 管理类型(In .net4.5) 之 使用类型

    1. 概述 本章介绍 值类型的装箱拆箱.类型转换 以及 C#4.0新推出的 dynamic 关键字. 2. 主要内容 2.1 装箱和拆箱 2.2 类型转换 有四种方式可以实现类型转换: ① 隐式转换: ...

  3. 第六章 管理类型(In .net4.5) 之 创建类型

    1. 概述 本章内容包括 C#5中如何更好的创建类型以及如何扩展现有类型. 2. 主要内容 2.1 如何选择类型 C#类型系统包括三种类型:值类型.引用类型.指针类型.(指针类型用于非托管代码,很少使 ...

  4. 第九章 管理类型(In .net4.5) 之 继承机制

    1. 概述 本章包括 设计和实现接口.创建和使用基类 以及 使用.net类库提供的标准接口. 2. 主要内容 2.1 设计和实现接口 一个接口包含公共的方法.属性.事件.索引器.类和结构都可以实现接口 ...

  5. 第二十一章 数据访问(In .net4.5) 之 序列化

    1. 概述 应用程序间传递数据,需要先将数据对象转化为字符流或字节流的形式,然后接收端收到后再转化回原始的数据对象.这就是序列化与反序列化. 本章介绍 .net中的序列化与反序列化.序列化器的种类 以 ...

  6. 第十章 管理类型(In .net4.5) 之 使用反射

    1. 概述 一个.net程序不仅包含代码和数据,还包含 元数据. 本章介绍如何应用attributes以及如何使用反射来获取它,还有如何使用CodeDom和expression trees来实现在运行 ...

  7. 第八章 管理类型(In .net4.5) 之 加强封装

    1. 概述 本章内容包括 访问控制符.属性 和 显式接口实现. 2. 主要内容 2.1 访问控制符 封装的核心是隐藏信息.访问控制符用来实现类型成员的访问控制. C#的访问控制符有:public, i ...

  8. 第十一章 Function类型

    在ECMAScript中,Function(函数)类型实际上是对象.每个函数也是Function类型的实例,而且都与其它引用类型一样具有属性和方法.由于是函数对象,因此函数名实际上也是一个指向函数对象 ...

  9. 第三章 设计程序架构 之 设计实现Windows Azure 角色生命周期

    1. 概述 Windows Azure 是微软的云计算平台.用于 在微软数据中心 通过全局网络 生成.发布和管理应用程序. 本章内容包括 startup tasks 以及  实现 Start, Run ...

随机推荐

  1. js 未结束的字符串常量错误解决方法

    1.JAVASCRIPT引用时,使用的字符语言不一致. 比如:<script type=”text/javascript” src=”xxx.js” charset=”UTF-8″>.xx ...

  2. iOS UIButton 设置图片文字垂直排列

    后面经过测试,如果button的文字长度变更,会导致图片位置变化,经过多次修改UIEdgeInsets的值也没有达到期望效果,最终采用集成UIButton类,重写layoutSubviews函数实现, ...

  3. CDN缓存策略FAQ

    1.CDN加速原理通过动态域名解析,网友的请求被分配到离自己最快的服务器.CDN服务器直接返回缓存文件或通过专线代理原站的内容.网络加速+内容缓存,有效提供访问速度 2.CDN节点数量全国多个机房,每 ...

  4. Nodejs文件服务器

    最近一直在忙于一个比较大的项目,在项目中需要有个文件服务器来支持.老鸟们建议我去用NodeJs来实现,我在接手这个项目之前其实并不了解NodeJs,但是一直想去了解.借着这个机会好好去学习一下.下面是 ...

  5. Flash视频播放器开发经验总结

    HTTP协议更优 目前几乎所有的视频点播网站全部采用HTTP协议传输数据.因为相对于诸如RTMP等协议来说,HTTP协议是无状态的,数据传输完毕就断开连接,这样服务器就可以腾出资源来服务更多的用户.而 ...

  6. POI实现word文档转html文件

    POI word文件转html package com.feiruo.officeConvert; import java.io.BufferedWriter; import java.io.File ...

  7. 慕课网-安卓工程师初养成-2-2 认识Java标识符

    来源:http://www.imooc.com/code/1177 问:标识符是神马? 答:标识符就是用于给 Java 程序中变量.类.方法等命名的符号. 使用标识符时,需要遵守几条规则: 1.  标 ...

  8. imp-00002 无法打开。。

    路径错了无疑 文件名少了个字符无疑 文件名错了无疑

  9. 解决在 使用 AjaxFileUploder 插件时,不能获取返回的 json 结果数据

    在MVC  项目 中使用 AjaxFileUploader 这个插件时,在上传图片或文件时,在控制器中返回的是 json数据,可是在 ie,或 googleChrome 浏览器中却出现 返回的json ...

  10. android View 继承关系

    二. View  SurfaceView  GLSurfaceView   View SurfaceView GLSurfaceView 功能 显示视图,内置画布,提供图形绘制函数.触屏事件.按键事件 ...