垃圾收集保证

Mar*_*ork 8 c# garbage-collection

对垃圾收集器有什么保证?

根据我的研究,我找到了:

  • 如果仍然存在对内存的引用,则不会对其进行垃圾回收
  • 如果没有参考:
    • 当它是GC是非确定性的
    • 当GC释放时,终结器将在释放内存之前运行.
    • 无法保证终结者的顺序(所以不要假设父母将在孩子之前运行).

但我真正想知道的是:

是否保证所有内存最终都将被垃圾收集并且终结器(析构函数)在对象上运行(假设程序退出很好).例如,最终退出时没有内存压力的应用程序会强制GC查找所有对象并确保调用终结器(析构函数)(包括静态成员变量)?

我在这个页面上找到了一个引用:http: //www.c-sharpcorner.com/UploadFile/tkagarwal/MemoryManagementInNet11232005064832AM/MemoryManagementInNet.aspx

此外,默认情况下,当应用程序退出时,不会为无法访问的对象调用Finalize方法,以便应用程序可以快速终止.

但我不确定这句话是多么权威.

我还找到了文档: CriticalFinalizerObject

Wim*_*nen 3

是否保证所有内存最终都会被垃圾收集,并且终结器(析构函数)在对象上运行(假设程序正常退出)。

不可以。从Object.Finalize文档中可以清楚地看出,如果出现以下情况,则可能不会调用终结器:

  • 其他一些终结器无法正确完成:

    另一个终结器无限期地阻塞(进入无限循环,尝试获取它永远无法获取的锁,等等)。由于运行时尝试运行终结器直至完成,因此如果终结器无限期阻塞,则可能不会调用其他终结器。

  • 其他一些终结器会创建更多可终结对象,从而无法终结所有可终结对象:

    仅当可终结对象的数量继续减少时,运行时才会在关闭期间继续终结对象。

  • 其他一些终结器会抛出异常:

    如果 Finalize 或 Finalize 的重写引发异常,并且运行时不是由重写默认策略的应用程序托管,则运行时将终止进程,并且不会执行任何活动的 try-finally 块或终结器。如果终结器无法释放或销毁资源,此行为可确保进程完整性。

话虽如此,除非绝对必要,否则您不想使用终结器的原因还有很多。

  • 它们会减慢垃圾收集器的速度(甚至可能会减慢垃圾收集器的速度,导致内存回收的速度不如其用完的速度快)。
  • 它们在另一个线程上运行,从而带来多线程问题。
  • 它们不是按确定的顺序执行的。
  • 它们可以复活已经最终确定的对象(并且除非明确重新注册以最终确定,否则不会再次最终确定)。