【问题标题】:Objects containing FINALIZE method?包含 FINALIZE 方法的对象?
【发布时间】:2015-01-09 01:04:03
【问题描述】:

猜想标题已经为您提供了我想知道的足够的想法,但我必须在这里稍微详细说明一下,以便您了解确切的想法。

我对@9​​87654324@方法的了解如下:

  1. 我们需要在 C# 中使用类中的~Classname 创建一个析构函数。根据C#,Finalize&析构函数是同义词(我在MSDN上看过,不知道最后那部分说法对不对)。

  2. 用于“优雅地释放非托管资源”。

  3. 它可以由用户(开发人员)相应地调用,或者当应用程序内存不足时(托管堆)或在应用程序结束时调用。

  4. 任何具有Finalize 方法的对象都将在运行时添加到终结队列

下图取自MSDN Magazine Article。它显示了根、托管堆 (MH)、终结队列 (FQ) 和可访问队列 (F-RQ)。 所有这些过程都发生在运行时。


我的问题如下:

  1. 如何将 MH 中存在的对象的引用添加到 FQ? (意思是,他们是因为有Finalize而自动添加到FQ,还是GC通过跟踪来添加它们。)

  2. GC 是否也通过 FQ 来清除引用? (对于使用GC.SuppressFinalization的对象引用。)

  3. 如果 MH 有足够的内存用于传入对象一段时间,但同时 F-RQ 中的特殊线程使用 F-RQ 中存在的引用的 Finalize 方法完成那么,此时 GC 是专门为 F-RQ 运行以回收内存,还是为 MH 和 F-RQ 运行,还是等到 MH 内存不足?

编辑:

对于问题 3:考虑下图,其中 F-RQ 中的所有引用都无法访问。

如果上述问题或知识有任何错误,欢迎指出 非常感谢它的解释和解释。

【问题讨论】:

    标签: c# garbage-collection clr finalize


    【解决方案1】:
    1. 当对象具有终结器时,GC 会将对象添加到终结器队列中。我不明白您在“自动添加,因为它们具有最终确定”和“GC 添加它们”之间的区别。 GC 添加它们因为它们有一个终结器。从程序员的角度来看,它是自动的。

    2. 当一个对象调用GC.SuppressFinalize() 时,它被标记为不需要完成。 GC 无需稍后“运行”队列以删除该对象的引用。处理队列时它会被忽略。

    3. 是的。 IE。首先,没有一个“GC”……存在几种不同的 .NET 实现。其次,GC 非常复杂,无法真正将其行为总结为那样。

    请注意,所有这些都是实现细节。以下是我们作为 C# 用户需要了解的内容:

    • 如果我们使用无法通过SafeHandle 类管理的非托管资源,我们需要向我们的类添加一个终结器,并在终结器中释放这些资源。
    • 在这种情况下(以及其他)我们还需要实现 IDisposable,并在我们的实现中调用 GC.SuppressFinalize(),以便 GC 知道不要浪费时间运行我们的终结器。

    其余的可以随时更改。这可能在学术上很有趣,或者如果您想编写自己的 GC。但除此之外,它通常不是可操作的信息。

    除了您已经参考过的文章,您可能还感兴趣:

    MSDN Blogs > cbrumme's WebLog > Finalization

    Object.Finalize Method – How finalization works

    SO: Generational Garbage collection Vs Garbage collection in .NET

    【讨论】:

    • @Peter By automatically added because they have Finalize 我的意思是如果一个对象有 Finalize 方法,它会自动到达 FQ 在运行时拥有自己的。 GC adds them 我的意思是,当一个对象有一个 Finalize 方法而不是在运行时,它会被跟踪并由 GC 添加在 FQ.
    • @LasseV.Karlsen 没有冒犯,但据我所知,Finalize Queue & F-Reachable Queue@ 987654336@ 是 2 种不同的数据结构,均由 GC 控制
    • @PeterDuniho 在运行期间,当GC 找到任何带有Finalize 的对象时,它会将其添加到MH 以及它们对FQ的引用 并执行他们的 Fianlize 方法 GC 将对象添加到 F-RQ
    • @beginner:在运行时,当一个对象被创建时,它已经是托管堆的一部分。如果它有一个终结器,它也会被添加到终结队列中。当终结器队列中的对象符合收集条件时,它就会被放入 freachable 队列中。我相信引用的链接包含此信息。
    • @beginner:我是说 GC 运行它的线程有时是由 GC 自己的算法控制的。我实际上并不知道当前实现的具体细节,但我不会惊讶地发现终结器线程(假设仍然只有一个)有时可以立即运行,有时不能。
    猜你喜欢
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 2020-05-04
    • 2015-02-02
    • 2023-01-05
    相关资源
    最近更新 更多