【转】.net框架读书笔记---CLR内存管理\垃圾收集(三)

接上一篇.net框架读书笔记---CLR内存管理\垃圾收集(二),主要学习了终止化对象(实现了Finalize方法的对象),了解了终止化对象的弊端,学习了通过实现IDisposable接口,通过Dispose方法来清理非托管资源,从而减轻垃圾收集器的压力,本节继续学习。

一、使用实现了Dispose模式的类型

  System.IO.FileStream其基类Stream实现了IDisposable接口:

class Program
{
static void Main( string [] args)
{
// 创建要写入临时文件的字节
byte [] b = new byte [] { 1 , 2 , 3 , 4 , 5 };
FileStream fs = new FileStream( " temp.dat " , FileMode.Create);

// 写入临时文件
fs.Write(b, 0 , b.Length);


fs.Close();
// fs.Write(b, 0, b.Length); // 该行会爆出异常,试图写入关闭的文件

File.Delete( " temp.dat " );
}

}

 

  上面的代码如果File.Delete之前不调用close是会报错的,delete之前必须保证文件已经关闭。注意调用CLose方法后FileStream对象仍然在托管堆中,最后垃圾收集器会运行,并将该FileStream对象判定为可收集的垃圾。这时垃圾收集器本来应该调用FileStream对象上的Finalize方法,但是因为Dispose方法调用了GC的SuppressFinalize方法,所以Finalize方法不再被调用,对象的内存直接被回收。

二、C#的using语句

  上面的例子应该使用try/catch块中如下:

class Program
{
static void Main( string [] args)
{
// 创建要写入临时文件的字节
byte [] b = new byte [] { 1 , 2 , 3 , 4 , 5 };
FileStream fs = new FileStream( " temp.dat " , FileMode.Create);

try
{
// 写入临时文件
fs.Write(b, 0 , b.Length);
}
catch
{
// do someting
}
finally
{
fs.Close();
}
// fs.Write(b, 0, b.Length); // 该行会爆出异常,试图写入关闭的文件

File.Delete( " temp.dat " );
}

}

  对于上述代码C#提供了更为简洁的语法,可以使用using语句

class Program
{
static void Main( string [] args)
{
// 创建要写入临时文件的字节
byte [] b = new byte [] { 1 , 2 , 3 , 4 , 5 };

using (FileStream fs = new FileStream( " temp.dat " , FileMode.Create))
{
// 写入临时文件
fs.Write(b, 0 , b.Length);
}
// fs.Write(b, 0, b.Length); // 该行会爆出异常,试图写入关闭的文件

File.Delete( " temp.dat " );
}

}

  首先在using语句内初始化一个对象,并将其引用保存在一个变量内。然后在using大括号内访问该变量。当编译这段代码,编译器会自动创建一个try和finalily块。在finally内编译器会调用其Dispose方法,显然,using语句只能用于那些实现了IDisposable接口的类型。

  上面代码的IL为

.method private hidebysig static void Main( string [] args) cil managed
{
.entrypoint
// 代码大小 76 (0x4c)
.maxstack 4
.locals init ([ 0 ] uint8[] b,
[ 1 ] class [mscorlib]System.IO.FileStream fs,
[ 2 ] bool CS$ 4 $ 0000 )
IL_0000: nop
IL_0001: ldc.i4. 5
IL_0002: newarr [mscorlib]System.Byte
IL_0007: dup
IL_0008: ldtoken field valuetype ' <PrivateImplementationDetails>{7FD0DAA5-56D7-474F-B21D-5AECDF07BAFB} ' / ' __StaticArrayInitTypeSize=5 ' ' <PrivateImplementationDetails>{7FD0DAA5-56D7-474F-B21D-5AECDF07BAFB} ' :: ' $$method0x6000001-1 '
IL_000d: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray( class [mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
IL_0012: stloc. 0
IL_0013: ldstr " temp.dat "
IL_0018: ldc.i4. 2
IL_0019: newobj instance void [mscorlib]System.IO.FileStream::.ctor( string ,
valuetype [mscorlib]System.IO.FileMode)
IL_001e: stloc. 1
. try
{
IL_001f: nop
IL_0020: ldloc. 1
IL_0021: ldloc. 0
IL_0022: ldc.i4. 0
IL_0023: ldloc. 0
IL_0024: ldlen
IL_0025: conv.i4
IL_0026: callvirt instance void [mscorlib]System.IO.Stream::Write(uint8[],
int32,
int32)
IL_002b: nop
IL_002c: nop
IL_002d: leave.s IL_003f
} // end .try
finally
{
IL_002f: ldloc. 1
IL_0030: ldnull
IL_0031: ceq
IL_0033: stloc. 2
IL_0034: ldloc. 2
IL_0035: brtrue.s IL_003e
IL_0037: ldloc. 1
IL_0038: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_003d: nop
IL_003e: endfinally
} // end handler
IL_003f: nop
IL_0040: ldstr " temp.dat "
IL_0045: call void [mscorlib]System.IO.File::Delete( string )
IL_004a: nop
IL_004b: ret
} // end of method Program::Main

很明显可以看到try/finally,刚才试了一下,using不能处理异常的,看上面的IL会发现,其没有catch,感觉很不爽。using也不能滥用,避免过早的调用了dispose。导致应用程序产生异常(ObjectDisposeException)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql实验三单表和多表查询_数据库实验三(单表查询)

实验三:select sno,snamefrom student;//(1)查询全体学生的学号和姓名select *from student;//(2)查询全体学生的详细记录select sname,sage,sdeptfrom student where sdeptMA;//(3)查询软件学院的学生姓名、年龄、系别select distinct snofrom sc;//(4)查询所有选修过课程的学…

【转】.net框架读书笔记---CLR内存管理\垃圾收集(四)

弱引用 当一个根指向一个对象时&#xff0c;该对象不可能被垃圾收集器收集&#xff0c;在这种情况下&#xff0c;通常说存在一个该对象的强引用&#xff08;strong reference&#xff09;。垃圾收集器还支持弱引用&#xff08;weak reference&#xff09;的概念。弱引用允许垃圾…

1756冗余_AB冗余模块1756-RM

AB冗余模块1756-RM100-C30UKJ01100-C30UKJ10100-C30UKL00100-C30UKL10AB冗余模块1756-RM100-C30UKP00100-C30UL00AB冗余模块1756-RM100-C30UL10100-C30UN00AB冗余模块1756-RM100-C30UN10100-C30UP001756-RM ControLogix冗余模块140U-H-RM12B 140U塑壳断路器外部附件1756-RMC1 C…

【转】.net框架读书笔记---CLR内存管理\垃圾收集(五)

对象复苏 当一个终止化对象被认为死亡时&#xff0c;垃圾收集器可以强制使该对象获得重生&#xff08;进入终止化可达队列&#xff09;&#xff0c;因为这样才能调用对象的Finalize方法。在Finalize方法被调用之后&#xff0c;它才算真正的死亡了&#xff0c;一个终止化对象会经…

imp命令导入指定表_Oracle—— 导入/导出 数据:exp,imp 命令

exp&#xff0c;imp 命令是需要在windows 的 cmd 命令中执行的命令&#xff0c;主要用于数据的导入和导出工作&#xff0c;方便高效。远程地址—— ip&#xff1a;port/orcl 注&#xff1a;该远程地址不写&#xff0c;就意味着执行本地的库。Oracle的数据导出(1)导出数据的…

【转】.net框架读书笔记---CLR内存管理\垃圾收集(六)

对象代龄 代龄是旨在提高垃圾收集器性能的一种机制。有以下几点&#xff1a; 对象越新&#xff0c;其生存期越短&#xff1b;对象越老&#xff0c;其生存期越长&#xff1b;对托管堆的一部分执行垃圾收集要比对整个托管堆执行垃圾收集速度要快。在托管堆初始化时&#xff0c;其…

MySQL数据库开发理念_mysql之数据库基本理念

数据储存的问题&#xff1a;数据冗余和不一致数据访问困哪数据孤立完整性原子性问题例如AB2个账户&#xff0c;从A中向B转钱&#xff0c;不管如何转&#xff0c;A和B的总量是保持不变的。只要A减少&#xff0c;B就增加。并发访问异常安全性问题文件的分层&#xff1a;表示层&am…

【转】.net框架读书笔记---CLR内存管理\垃圾收集(七)

编程控制垃圾收集器 System.GC类型为应用程序提供了直接控制垃圾收集器的一些方法&#xff0c;可以通过GC.MaxGeneration来查询托管堆支持的最大代龄&#xff0c;目前为2。 通过下面方法执行垃圾收集器 GC.Collect(int);传递代龄&#xff0c;传递0&#xff0c;收集0代&#xff…

少年自学python笔记_自学python 笔记

print() 输入input() 输出python能够处理的数据类型:整数、浮点数、字符串("\"转义符,\n 换行)、布尔值/布尔代数(True、False(and【或】、or【于】、not【非】))(and&#xff1a;只有所有都为True&#xff0c;and运算结果才为True)(or:只要一个为True&#xff0c;or…

【转】深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 1

前言 虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC)&#xff0c;但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC)。另外&#xff0c;了解内存管理可以帮助我们理解在每一个程序中定义的每一个变量是怎样工作的。 简介 这篇文章我们将介绍一些方…

java解析string_java读取文件内容为string字符串的方法

直接就把项目中的方法贴出来吧/*** 读出城市列表文件*/private String readCityFile() {File file02 new File(path_xinfu, "/cityList.json");FileInputStream is null;StringBuilder stringBuilder null;try {if (file02.length() ! 0) {/*** 文件有内容才去读文…

【转】深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 2

前言 虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC)&#xff0c;但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC)。另外&#xff0c;了解内存管理可以帮助我们理解在每一个程序中定义的每一个变量是怎样工作的。 简介 继续上篇未完成的“参数传…

java 引用被回收_java GC 静态List 如果没有引用会被回收吗

垃圾收算法1.引用计数法(Reference Counting Collector)2.tracing算法(Tracing Collector)3.compacting算法(Compacting Collector)4.copying算法(Coping Collector)5。generation算法(Generational Collector)6.adaptive算法(Adaptive Collector)一个新的对象被创建&#xff0…

【转】深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第五节 引用类型复制问题及用克隆接口ICloneable修复

前言 虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC)&#xff0c;但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC)。另外&#xff0c;了解内存管理可以帮助我们理解在每一个程序中定义的每一个变量是怎样工作的。 简介 这一节我们将介绍引用类型…

linux virt java_Linux下Java环境安装

本节主要讲解Linux(Centos 6.5)下Java环境的安装1. 卸载机器上默认安装的JDK在Linux环境下一般会默认安装jdk&#xff0c;为了自己项目的开发部署&#xff0c;一般情况要重新装jdk&#xff0c;而且自己装的Jdk相对来说易控制版本&#xff0c;稳定性更高。所以以下是我卸载预装J…

【转】深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC,提搞程序性能****

前言 虽然在.Net Framework 中我们不必考虑内在管理和垃圾回收(GC)&#xff0c;但是为了优化应用程序性能我们始终需要了解内存管理和垃圾回收(GC)。另外&#xff0c;了解内存管理可以帮助我们理解在每一个程序中定义的每一个变量是怎样工作的。 简介 这一节我们将介绍垃圾回…

java下拉列表 动态_【示例】教你简单用Java写一个动态更新的下拉列表(无数据库)...

动态更新下拉列表varxmlHttp;functioncreatXMLHttpRequest(){if(window.ActiveXObject){xmlHttpnewActiveXObject("Microsoft.XMLHTTP");}else if(window.XMLHttpRequest){xmlHttpnewXMLHttpRequest();}}functionupdateSelect(){varselecteddocument.all.slt1.value;…

【转】分布式事务的常见解决方案

一、事务起步 1. 什么是事务 事务这种东西大家都耳熟能详了&#xff0c;通常指由一组操作组成的一个工作单元&#xff0c;这一整个组合要么全部成功&#xff0c;要么全部失败。 2. 本地事务 在计算机系统中&#xff0c;更多的是通过关系型数据库来控制事务&#xff0c;这是…

深入解析java web_java进阶--深入分析java Web

第一章&#xff1a; 深入了解Web请求整理本书的内容与之前的采用相同的方式&#xff0c;主要目的还是为了可以仔细的阅读。整理自己的见解。这本书整体的感觉很好&#xff0c;思路很清晰&#xff0c;最近就发现&#xff0c;国人写的文字和外国译文相差很大&#xff0c;主要体现…

【转】修饰符new将父类中的该方法隐藏掉有什么意义 不隐藏有什么弊端

这是一个C#语法的问题。子类如果要重写父类的方法的话&#xff0c;virtual-override一定成对的。 子类不重写&#xff0c;而是创建一个属于自己的同名方法&#xff0c;就最好加个new。如果不加new也等于new&#xff0c;但是编译器都会提醒你&#xff0c;加个标识比较好。 区别见…