首 页 | 网页模板 | 教程 | 源码下载 | 书籍下载 | 图片素材 | 字体 | JAVA特效 | FLASH源码 | 软件 | 矢量 | 论坛 | 其它 |
设为主页
加入收藏
联系站长
平面设计 | 网页制作 | 程序编写 | 数 据 库 | 媒体动画 | 网络冲浪 | 服务器相关 |
当前在线
广告:P4服务器电信机房6999/年即送产权 | 疾风下载
值类型的Finalize不会被调用?
2005-11-12 20:38:33  作者:模板天下收集整理  来源:未知 网友评论 0 条 论坛
  

Finalize,即.NET类型的非确定性析构器,将在对象被GC检查回收前调用。现在我关心一个问题,值类型,一般是自定义struct的析构器会不会被调用呢?一般值类型是在栈上分配,因此就不在托管堆上,不存在被GC回收的情况。但是我们要是将值类型装箱以后放在托管堆里了呢?他的析构器会不会被调用呢?由于C#和C++对析构器语法特别对待,我们不能在struct里面直接重写Finalize方法,因此这个实验只能用VB来做:

Public Structure A
    Public i As Integer

    Protected Overrides Sub Finalize()
        MsgBox("Hi, finalized")
    End Sub
End Structure

在这个类里面,我们名目张胆地重写了Finalize,并且没有调用基类的Finalize,幸好VB对这种行为视而不见。首先我们检查是不是真的成功重写了基类的方法,用以下代码测试一下:

Dim x As Object = New A

GetType(Object).GetMethod("Finalize", BindingFlags.NonPublic Or _
    BindingFlags.Instance _
    ).Invoke(x, New Object() {})

结果顺利显示了结果。接下来就进入主题,将该装箱后的对象抛弃在托管堆中,然后调用GC.Collect回收,看看是否能启动Finalize:

Dim x As Object = New A

x = Nothing
GC.Collect()

结果……没有运行!?难道是这段代码无法达成调用Finalize的条件?我将Structure换成Class试试看,结果马上显示Finalize被调用了。这说明Finalize对值类型确实不管用。那么是不是因为CLR内部在某处对值类型自动调用GC.SuppressFinalize之类的方法注销了Finalize呢?那好,我们就多给他注册几个试试:

Dim x As Object = New A


GC.ReRegisterForFinalize(x)
GC.ReRegisterForFinalize(x)
......

x = Nothing
GC.Collect()

结果,不管写了几次GC.ReRegisterForFinalize,在GC回收x的时候仍然没有Finalize运行的踪迹。看来,在CLR内部,值类型的Finalize是有特定规则的,不按照一般类的方式运行。我也没研究CLR的机制,没法再深究这个过程原理,以后有机会要好好看看……

共分1页  [1] 
>> 相关文章

关于网站 | 客服中心 | 服务条款 | 友情链接 | 广告联系 | 本站历程 | 网站导航

吉ICP备05000107号