第十一章 管理类型(In .net4.5) 之 管理对象的生命周期
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) 之 管理对象的生命周期的更多相关文章
- 第十二章 管理类型(In .net4.5) 之 操作字符串
1. 概述 本章包括 字符串基本操作 以及 查找.遍历.格式化字符串. 2. 主要内容 2.1 在.net平台中使用字符串 C#中,string是用来保存文本信息的.是一个被当做值类型使用的引用类型. ...
- 第七章 管理类型(In .net4.5) 之 使用类型
1. 概述 本章介绍 值类型的装箱拆箱.类型转换 以及 C#4.0新推出的 dynamic 关键字. 2. 主要内容 2.1 装箱和拆箱 2.2 类型转换 有四种方式可以实现类型转换: ① 隐式转换: ...
- 第六章 管理类型(In .net4.5) 之 创建类型
1. 概述 本章内容包括 C#5中如何更好的创建类型以及如何扩展现有类型. 2. 主要内容 2.1 如何选择类型 C#类型系统包括三种类型:值类型.引用类型.指针类型.(指针类型用于非托管代码,很少使 ...
- 第九章 管理类型(In .net4.5) 之 继承机制
1. 概述 本章包括 设计和实现接口.创建和使用基类 以及 使用.net类库提供的标准接口. 2. 主要内容 2.1 设计和实现接口 一个接口包含公共的方法.属性.事件.索引器.类和结构都可以实现接口 ...
- 第二十一章 数据访问(In .net4.5) 之 序列化
1. 概述 应用程序间传递数据,需要先将数据对象转化为字符流或字节流的形式,然后接收端收到后再转化回原始的数据对象.这就是序列化与反序列化. 本章介绍 .net中的序列化与反序列化.序列化器的种类 以 ...
- 第十章 管理类型(In .net4.5) 之 使用反射
1. 概述 一个.net程序不仅包含代码和数据,还包含 元数据. 本章介绍如何应用attributes以及如何使用反射来获取它,还有如何使用CodeDom和expression trees来实现在运行 ...
- 第八章 管理类型(In .net4.5) 之 加强封装
1. 概述 本章内容包括 访问控制符.属性 和 显式接口实现. 2. 主要内容 2.1 访问控制符 封装的核心是隐藏信息.访问控制符用来实现类型成员的访问控制. C#的访问控制符有:public, i ...
- 第十一章 Function类型
在ECMAScript中,Function(函数)类型实际上是对象.每个函数也是Function类型的实例,而且都与其它引用类型一样具有属性和方法.由于是函数对象,因此函数名实际上也是一个指向函数对象 ...
- 第三章 设计程序架构 之 设计实现Windows Azure 角色生命周期
1. 概述 Windows Azure 是微软的云计算平台.用于 在微软数据中心 通过全局网络 生成.发布和管理应用程序. 本章内容包括 startup tasks 以及 实现 Start, Run ...
随机推荐
- UITableViewCell之微博篇
微博篇 本应用所涉及的知识点: 1.UITableView 中的cell 2.模型的创建 3.MJExtension第三方框架的使用 需求分析 1.界面分析 微博界面 界面控件分析: 整个页面 1.不 ...
- 《Code Complete》ch.25 代码调整策略
WHAT? 本章讨论程序性能调整问题.但是对用户来说,程序员按时交付软件,提供一个清爽的用户界面,避免系统经常死机常常比程序性能更加重要 WHY? 在程序设计这种文化中,编写出能够节省几微秒的代码可以 ...
- POJ1298_The Hardest Problem Ever_最难的问题_Caesar 密码_C++
题目:http://poj.org/problem?id=1298 好吧,给了题目也看不懂……给出翻译(题目名翻译是:最难的问题,233333) 这一看就是老师给出题解: 然而没有什么用哈 最快的办法 ...
- jmeter随笔(1)-在csv中数据为json格式的数据不完整
昨天同事在使用jmeter遇到问题,在csv中数据为json格式的数据,在jmeter中无法完整的取值,小怪我看了下,给出解决办法,其实很简单,我们一起看看,看完了记得分享给你的朋友. 问题现象: 1 ...
- 解决“C:\Windows\System32\ntdll.dll”。无法查找或打开 PDB 文件问题
这些提示的问题完全没有必要去理会,因为一般情况下你点击本地windows调试,会报出这样问题很正常. 网上一些介绍什么要去选项卡栏勾选window连接器什么鬼,不建议用该方式,一旦你勾选那个方式虽然不 ...
- C++调用WebService服务问题总结
近期接手一部分C++研发工作,同时与.NET开发小组进行软件功能协作,于是需要调用.NET WebService服务,已完成数据的网络通讯业务功能:结束之余,将手头碰到的问题总结罗列如下: C++如何 ...
- Javascript与Flex AS3的交互
网上看了很多的关于JS和AS的教程,写的都玄乎乎,让一帮新人摸不着头脑. 鉴于此,打算自己写一个简化的教程. 重点: ExternalInterface.addCallback("js_fu ...
- 无法读取配置节“protocolMapping”,因为它缺少节声明
无法读取配置节“protocolMapping”,因为它缺少节声明 1.正常情况 : Web.config文件中有protocolMapping节点, 发现在IIS部署时使用了.NET 2.0的 ...
- C#导出
#region DataReader 的数据导出到Excle 中 //public string Exports(string str_sql) //{ / ...
- JS常用的设计模式(11)—— 中介者模式
中介者对象可以让各个对象之间不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互. 打个比方,军火买卖双方为了安全起见,找了一个信任的中介来进行交易.买家A把钱交给中介B,然后从中 ...