面试出现频率:经常出现,但通常不会问的十分深入。通常来说,看完我这篇文章就足够应付面试了。面试时主要考察垃圾回收的基本概念,标记-压缩算法,以及对于微软的垃圾回收模板的理解。知道什么时候需要继承IDisposible接口,解构函数是做什么用的,什么时候需要自己写一个解构函数。
重要程度:10/10
参考书籍:CLR via C#,其对垃圾回收讲解的十分详细,有些内容甚至过于高深。熟悉垃圾回收可以使你的程序更加健壮,性能更好。
垃圾回收的主要操作对象是托管堆,托管堆包括GC堆和加载堆。
GC堆里面为了提高内存管理效率等因素,分成多个部分,其中两个主要部分为:
加载堆不受GC管辖。加载堆上的主要对象有类型对象和它们的静态字段,字符串驻留池等。几个非托管资源的例子:StreamWriter,数据库连接对象等。
你可以继承IDisposible接口,然后在Dispose方法中销毁任何资源,包括非托管资源。但如果你忘记了调用它,那么你的非托管资源将没有任何机会得到释放。只有当你的类型含有非托管资源,或者实现了IDisposible的托管资源时,你才需要继承IDisposible接口,实现一个Dispose。 如果你只面对一堆托管资源,并且它们都没有实现IDisposible时,你不需要做任何事。
如果类型没有非托管资源,此时,因为所有托管资源肯定都有Finalize方法,我们不需要实现解构函数。特别的,对于实现了IDisposible的类型,我们只需要简单的调用Dispose来释放资源即可(这会调用那个类型的Dispose方法,如果类型是属于微软的,则微软已经给你实现好了)。有些类型的Dispose方法的名称为Close。
如果你的托管资源包含了一些实现了IDisposible接口的成员时,你要继承IDisposible接口,并在Dispose方法中将这些成员回收。或者,你在使用成员时,使用using关键字。using关键字本质上是一个try - finally块,所以即使你在using块中发生了异常,也不用担心,对象仍然会在finally块中被dispose。(曾经有面试官问过我这个问题)
如果你只是临时使用非托管资源,那么将其包含在using中就可以了,例如使用StreamWriter。
假设你的类型中含有非托管资源属性/字段,此时,你要继承IDisposible接口,实现Dispose方法,并写一个解构函数。你可以follow微软的垃圾回收模板,步骤如下:
public sealed class WindowStationHandle : IDisposable
{
// 非托管资源
public IntPtr Handle { get; set; }
public WindowStationHandle(IntPtr handle)
{
this.Handle = handle;
}
public WindowStationHandle()
: this(IntPtr.Zero)
{
}
public bool IsInvalid
{
get { return (this.Handle == IntPtr.Zero); }
}
// 私有方法
private void CloseHandle()
{
if (this.IsInvalid)
{
return;
}
if (!NativeMethods.CloseWindowStation(this.Handle))
{
Trace.WriteLine("CloseWindowStation: " + new Win32Exception().Message);
}
// 释放非托管资源
this.Handle = IntPtr.Zero;
}
public void Dispose()
{
//实现Dispose方法,呼叫私有方法,之后呼叫SuppressFinalize
this.CloseHandle();
GC.SuppressFinalize(this);
}
~WindowStationHandle()
{
//实现一个解构函数(这会覆盖原有的Finalize方法)在其中呼叫私有方法。
//这是为了防止用户忘了呼叫Dispose方法而最终没有回收这个非托管资源。
//原有的Finalize方法并不会理会非托管资源。
this.CloseHandle();
}
}
结合上面4.4,4.8和4.9,就构成了常规的垃圾回收策略:
大对象堆陷阱:http://www.cnblogs.com/brucebi/archive/2013/04/16/3024136.html
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有