关于C#的垃圾回收机制,Finalize和Dispose的区别(自认为很清晰了,有疑问的评论)
2021-05-29 15:05
标签:资料 数据区 car when 而在 nbsp 文件 中英文 数据流 来到个新地方,新学习C#,前面看到C#的垃圾回收,Finalize和Dispose时,总是一知半解,迷迷糊糊。这次好了,前面连续两次面试问到这个问题,脑子里不是很清晰,加上用英文来表达,更是雪上加霜的感觉。 回来,好好看了相关资料,从网上看,总没有人能说的很清晰,往往很深奥的样子,拿了本 现在主要是找工作,没有时间写详细,先就说个重点: 1. 垃圾回收器GC负责托管对象的回收。GC通过应用根对象(如全局变量,静态变量等)能否访问到来判断对象是否能回收。 而不是通过引用计数法来判断对象是否需要被回收,因为引用计数无法结局一个循环引用的两个对象的回收,他们的引用计数都为1,但实际这两个对象是整个应用程序中的孤岛对象, 应用程序根对象无法访问到,应该被回收。 2. 垃圾回收很耗性能,一般只在分配新对象发现空间不够用时才触发回收。具体回收时采用的算法是分步回收,即分代回收的方法,其基于统计原理。新产生的对象总是有最大的可能性被废弃不再使用,比如调用函数中的新分配的局部对象;而经过几次回收周期中存活下来的对象,则更不可能被回收掉,如全局变量等。 GC初始化默认每个对象都是需要回收的,回收触发时,检测根对象是否能访问到来判断对象是否真的可以回收。GC将对象标签为3代,分别是0,1,和2代对象。0代是还没有经过一次回收检测的对象,1代表示经过一次回收检测后存活下来(即不能回收)的对象,而2代表示经过2次以上检测仍存活的对象。 GC检测依照顺序,分别检测0代,1代和2代。但是如果检测到0代,回收部分对象后,发现空间已经足够新对象使用,回收检测立刻停止。如果仍然不够,才会继续检测1代对象,直至2代对象。通过这样的方法,避免垃圾回收机制产生作用时的性能消耗。大部分情况下,0代检测都足以起效。 1. C#中的Object,Class和reference的关系 Object是Class的一个实例,而Reference是一个指针。学过C/C++的很好理解,实际其内容是一个内存地址,该内存地址里存放的是实际的对象。 C#中所有的类的实例化都是通过引用实现,实际是使用new 来实例化一个类。如下举例说明: 其中变量refToMyCar实际就是一个引用,一个指针,指向实际的实例对象Car("Zippy", 50) 在C#中,引用refToMyCar和实例对象Car("Zippy", 50)是存放于不同的内存块中,分别叫做堆栈区和托管内存堆区; 程序的堆栈区是一个临时数据区,存放函数调用的对象,局部变量等,函数调用完存放于堆栈区的对象的生命期就结束了,每个线程都有固定大小的堆栈。 而堆是一个全局内存区,所有分配在Managed Heap的对象,需要管理何时释放。在C/C++语言中,这部分数据需要显示的delete和new配套使用,而在C#中,会被.NET CLR来管理,就是说你在托管堆中只管生成新的实例,而不用管该实例占用空间的释放,这由CLR自动管理,实际就是垃圾回收器干的事情。 2. 垃圾回收器(GC) GC是怎样知道一个对象不在使用了呢,这涉及到后面描述的具体算法,简而言之就是GC发现,无法从代码根应用到达的对象。可以以一个不太严谨的解释来理解,就是该分配在堆区的 对象,已经没有外部引用了。如下一段代码: Car的对象在函数外,没有可以引用到,就意味着该对象可以被回收了。 3. C#有两类对象,托管和非托管对象。这个托管指的是对象被谁管理,在.net框架里,就是被CLR托管。非托管对象,指的是一些操作系统提供的资源,比如文件句柄,Socket,数据库连接等。 这些资源对象的使用,需要像操作系统申请并且使用完后,及时的归还。比如C#的FileStream类,我们使用时有如下一段代码: 其中,finfo, fs, sw三个分别为FileInfo,FileStream,StreamWriter的对象。 关于C#的垃圾回收机制,Finalize和Dispose的区别(自认为很清晰了,有疑问的评论) 标签:资料 数据区 car when 而在 nbsp 文件 中英文 数据流 原文地址:https://www.cnblogs.com/dusf/p/11082190.htmlclass Program
{
static void Main(string[] args)
{
Console.WriteLine("***** GC Basics *****");
// Create a new Car object on the managed heap. We are returned a reference to this object ("refToMyCar").
Car refToMyCar = new Car("Zippy", 50);
// The C# dot operator (.) is used to invoke members on the object using our reference variable.
Console.WriteLine(refToMyCar.ToString());
Console.ReadLine();
}
}
static void MakeACar()
{
// If myCar is the only reference to the Car object, it *may* be destroyed when this
method returns.
Car myCar = new Car();
}
FileInfo finfo = new FileInfo(FilePath);
//以打开或者写入的形式创建文件流
using (FileStream fs = finfo.OpenWrite())
...{
//根据上面创建的文件流创建写数据流
StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
//把新的内容写到创建的HTML页面中
sw.WriteLine(strhtml);
sw.Flush();
sw.Close();
}
文章标题:关于C#的垃圾回收机制,Finalize和Dispose的区别(自认为很清晰了,有疑问的评论)
文章链接:http://soscw.com/index.php/essay/89169.html