今天来谈谈 C#的 GC,也就是垃圾回收机制,非常的受教,总结如下
首先:谈谈托管,什么叫托管,我的理解就是托付 C#运行环境帮我们去管理,在这
个运行环境中可以帮助我们开辟内存和释放内存,开辟内存一般用 new,内存是随机分配
的,释放主要靠的是 GC 也就是垃圾回收机制。哪么有两个大问题 1.GC 可以回收任何对
象吗?2.GC 什么时候来回收对象?回收那些对象?
对于第一个问题,GC 可以回收任何对象吗?我是这样理解的,首先要明白一点,C#
在 强 大 也 管 不 到 非 托 管 代 码 ? 哪 么 什 么 是 非 托 管 代 码 呢 ? 比 如 stream ( 文 件 ),
connection(数据库连接),COM(组件)等等。。哪么这些对象是需要进行连接的,
比 如 说 我 们 写 这 样 一 句 话 FileStream fs = new
FileStream(“d://a.txt”,FileMode.Open);实际上已经创建了和 d://a.txt 的连接,如果重
复两次就会报错。哪么 fs 这个对象叫做非托管对象,也就是说 C#
不能自动去释放和 d://a.txt 的连接。哪么对于非托管的代码怎么办,一会我来说。
对于第二个问题,GC 什么时候来回收,回收什么对象?我想后面的就不用我说了,
当然是回收托管对象了。但是 GC 什么时候回收?是这样的:GC 是随机的,没有人知道他
什么时候来,哪么我写了一个例子,证明这一点
private void button1_Click(object sender, EventArgs e)
{
AA a = new AA();
AA b = new AA();
AA c = new AA();
AA d = new AA();
}
public class AA{}
在讲这个例子之前,要明白什么被称之为垃圾,垃圾就是一个内存区域,没有被任何引用
指向,或者不再会被用到。哪么在第一次点击按钮的时候会生成 4 个对象,第二次点击按
钮的时候也会生成 4 个对象,但是第一次生成的 4 个对象就已经是垃圾了,因为,第一次
生成的 4 个对象随着 button1_Click 函数的结束而不会再被调用(或者说不能再被调
用),哪么这个时候 GC 就会来回收吗?不是的!我说了 GC 是随机的,哪么你只管点你
的,不一会 GC 就会来回收的(这里我们可以认为,内存中存在一定数量的垃圾之后,GC
会来),要证明 GC 来过我们把 AA 类改成
public class AA
{
~AA()
{
MessageBox.Show("析构函数被执行了");
}
}
要明白,GC 清理垃圾,实际上是调用析构函数,但是这些代码是托管代码(因为里面没
有涉及到 Steam,Connection 等。。)所以在析构函数中,我们可以只写一个 MsgBox
来证明刚的想法;这个时候,运行你的程序,一直点击按钮,不一会就会出现一大堆的“析
构函数被执行了”…
好了,然后让我们看看能不能改变 GC 这种为所欲为的天性,答案是可以的,我们可