【问题标题】:Destruction of .NET Objects by CLRCLR 破坏 .NET 对象
【发布时间】:2012-11-15 03:25:03
【问题描述】:

没有任何 dispose() 或 finalize 模式的 .NET 对象如何被 clr 销毁? 是否被Object Finalize方法清除!

【问题讨论】:

    标签: .net clr


    【解决方案1】:

    不,如果对象没有显式声明终结器,则它永远不会添加到 freachable 队列中 - 它的内存只是被回收。

    这是你不应该声明终结器的原因之一,除非你真的需要一个。任何具有终结器的对象都需要两次 GC 才能完全收集。


    来自Object.Finalize

    Object.Finalize 什么都不做 默认。它必须被覆盖 仅在必要时派生类, 因为垃圾期间的回收 收集往往需要更长的时间 如果必须运行 Finalize 操作。

    另外我建议您查看Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework

    【讨论】:

    • 那为什么我们需要 dispose 方法!
    • 这是他的意思,你不需要它。如果你想要它,你可以提供一个,CLR 将支付费用。
    • 另外,您可以在一个消耗大量内存的进程完成后手动调用 GC 来销毁这些对象。但并不总是建议这样做,因为调用 GC 本身可能会非常消耗资源。
    • 当有其他事情需要完成时,您通常需要它,而不仅仅是内存。例如,System.IO.File 类确实实现了一个终结器——它用于关闭文件句柄。此外,当一个类有一个终结器时,它通常实现System.IDisposable。这样你就可以在using statements中使用它。
    【解决方案2】:

    请参阅此article 以全面了解 Dispose 模式的作用。

    在某些情况下,您可能希望为使用对象的程序员提供在垃圾收集器释放对象之前显式释放这些外部资源的能力。如果外部资源稀缺或昂贵,如果程序员在不再使用资源时显式释放资源,则可以获得更好的性能。

    【讨论】:

    • 我知道 CLR 作为不同的线程运行。但是它是如何获得调用属于 App 线程的 finalize 方法对象的超级特权的。请记住,在典型的 bg 线程/GUI 中,我们需要执行 control.invoke!
    • @NSN:怎么样?很简单:终结器写得很好,不要抛出。它们不像其他 GUI 控制方法那样具有线程亲和性。你认为这有意义吗?
    【解决方案3】:

    垃圾收集器最终将回收对象使用的内存,因为它不再被任何引用访问。这是唯一会发生的清理,除非对象有终结器。

    【讨论】:

      【解决方案4】:

      将 .net 中的垃圾收集器想象成类似于保龄球馆置瓶机清除“死木”(撞倒的瓶)的方式可能是最简单的:

      1. 将所有不应清除的别针(即仍然站立的别针)移出小巷表面。
      2. 将清扫机扫过小巷的整个表面,彻底清除那里的任何东西。
      3. 放回别针。

      请注意,在操作的任何阶段,置瓶机都不会检测或瞄准任何被撞倒的瓶。它既不知道也不关心是否有一个这样的瓶或其中九个(如果没有瓶站立,置瓶机将记录一次击球并跳过一帧的后半部分)。从置瓶机的角度来看,这些瓶可能不存在,直到它们到达可以回收它们的机制。

      【讨论】:

        猜你喜欢
        • 2010-12-25
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 2015-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多