什么是终结器线程的范围 - 每个应用程序域或每进程? [英] What is the scope of finalizer thread - per application domain or per process?

查看:151
本文介绍了什么是终结器线程的范围 - 每个应用程序域或每进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我所有的阅读应该有一个GC线程调用所有终结。现在的问题是,这是什么一螺纹的范围。 - 每个进程或每个应用领域,如结构域的整意图是分离,并在一个进程空间中的独立不同的应用程序

Based on all my reading there should be one GC thread to invoke all finalizers. Now, the question is what is the scope of this "one" thread - per process or per application domain, as the whole intention of domains is to separate and make "independent" different applications in one process space.

我看了这里

如果在发生未处理的异常   终结CLR的执行线程   会吞下例外,治疗   终结,就好像它正常完成,   从freachable队列中删除   并移动到下一个项目。

If an unhandled exception occurs in a finalizer the CLR's executing thread will swallow the exception, treat the finalizer as if it completed normally, remove it from the freachable queue and move onto the next entry.

更严重,虽然,是什么情况   如果你的终结不退出的   由于某些原因,例如,它的块,   等待一个条件,即从未   发生。 在这种情况下,终结   线程将被挂起,所以没有更多的   终结对象将是垃圾   收取。您应该很   意识到这种情况,坚持   写简单的code释放你的   非托管资源的终结。

More serious though, is what happens if your finalizer doesn't exit for some reason, for example it blocks, waiting for a condition that never occurs. In this case the finalizer thread will be hung, so no more finalizable objects will be garbage collected. You should be very much aware of this situation and stick to writing the simplest code to free your unmanaged resources in finalizers.

另一个考虑因素是什么情况   在应用程序关闭。当。。。的时候   计划关闭的垃圾收集器   将努力致电终结   所有终结对象,但与   一定的局限性:

Another consideration is what happens during application shutdown. When the program shuts, the garbage collector will endeavour to call the finalizers of all finalizable objects, but with certain limitations:

      
  • 终结对象不松口   以在更高的堆世代   关机。

  • Finalizable objects are not promoted to higher heap generations during shutdown.

任何个人的终结将有   最多2秒的执行;如果它   需要更长的时间就会被杀死了。

Any individual finalizer will have a maximum of 2 seconds to execute; if it takes longer it will be killed off.

有最多40秒   所有终结要执行;如果有的话   终结仍在执行,或   未决在这一点,整个   过程突然死光了。

There is a maximum of 40 seconds for all finalizers to be executed; if any finalizers are still executing, or pending at this point the whole process is abruptly killed off.

太多的职位(甚至是正式文件)的术语应用程序,过程和应用程序域的滥用 - 其中大多数即使假设他们是平等的,因为通常应用在单个应用程序域中运行一个单一的过程。这误操作使得这些文档难以阅读,甚至不会有用的。

Too many posts (and even official documentation) misuse of the terms "application", "process" and "application domain" - most of them even assuming that they are equal, because usually applications are run in a single application domain in a single process. This misuse makes all of these docs hard to read, and not even useful.

所以,我的问题是假设一个以上的应用程序,在一个单一的过程中一个单独的应用程序域中的每个运行。

So, my question assumes more than one applications, each run in a separate application domain in a single process.

是否所有这些应用程序共享相同的GC和终结的主题?是否在上述文章中描述的问题(挂起终结器线程),将影响这一进程的所有应用程序?如果是的话 - 有一种变通方法(除了不使用坏的应用),喜欢莫名其妙地发现了终结器线程和发送Thread.Abort的

Does all these application share the same GC and finalizer threads? Does the problem described in the article above (hang finalizer thread) will affect all applications in that process? If yes - is there a workaround (besides to not use bad applications), like somehow to discover the finalizer thread and send it Thread.Abort?

以上所有是因为我打了类似的问题。我的应用程序在一个单独的应用程序域插件与第三方软件(Outlook)中运行。种种原因,因为我需要调用GC.Collect和GC.WaitForPendingFinalizers充分释放COM引用(通常互操作例程是不够的,处/ Outlook)中,当一个特定的第三方插件运行,我GC.WaitForPendingFinalizers挂起永远,所以我怀疑存在这样的第三方添加一个坏的终结。我有过更换/删除,添加(客户要求),所以我必须弄清楚我自己如何使它们并存无法控制的。

All above is because I hit similar problem. My application runs in a separate application domain as addin to third party software (Outlook). Because of various reasons I need to call GC.Collect and GC.WaitForPendingFinalizers to fully release COM references (the usual interop routines are not enough for Office/Outlook), when a particular other third party addin is running, my GC.WaitForPendingFinalizers hangs forever, so I suspect that there is a "bad" finalizer in that third party adding. I have no control over replacing/removing that adding (client's requirement), so I have to figure out on my own how to make them co-exist.

推荐答案

看起来它确实只是一个CLR每个实例的进程内的线程 - 此刻,无论如何。下面是一些code表明:

Looks like it is indeed just one thread per CLR instance within the process - at the moment, anyway. Here's some code to show that:

test.cs中:

using System;

class Test
{
    static void Main()
    {
        AppDomain.CreateDomain("First")
                 .ExecuteAssembly("ShowFinalizerThread.exe");
        AppDomain.CreateDomain("Second")
                 .ExecuteAssembly("ShowFinalizerThread.exe");
    }
}

ShowFinalizerThread.cs:

ShowFinalizerThread.cs:

using System;
using System.Threading;

class ShowFinalizerThread
{
    static Random rng = new Random();

    ~ShowFinalizerThread()
    {
        Console.WriteLine("Thread/domain: {0}/{1}",
                          Thread.CurrentThread.ManagedThreadId,
                          AppDomain.CurrentDomain.FriendlyName);
        if (rng.Next(10) == 0)
        {
            Console.WriteLine("Hanging!");
            Thread.Sleep(2000);
        }
    }

    static void Main()
    {
        new Thread(LoopForever).Start();
    }

    static void LoopForever()
    {
        while (true)
        {
            new ShowFinalizerThread();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Thread.Sleep(300);
        };
    }
}

编译每一个控制台应用程序,然后运行TEST.EXE(在命令行是最简单的,海事组织)。你会看到一个应用程序域的终结块另一回事。

Compile each as a console app, then run test.exe (from the command line is easiest, IMO). You'll see that one app domain's finalizer blocks another.

在未来,我也不会感到惊讶看到一终结器线程每个的内核的,而不是每个AppDomain - 但它听起来像是你仍然有问题:(

In the future I wouldn't be surprised to see one finalizer thread per core rather than per AppDomain - but it sounds like you'll still have problems :(

您有我最深切的同情(虽然不是一个解决方案) - 有一次我在Oracle的Blob追查陷入僵局。我们能够修复被处置得当,但我不知道一切正常,这很好! - 这是一个真正的痛苦,甚至发现一个

You have my deepest sympathy (though not a solution) - once I tracked down a deadlock in an Oracle Blob. We were able to fix that by disposing of it properly, but I know not everything works that nicely - and it was a real pain even finding that one!

这篇关于什么是终结器线程的范围 - 每个应用程序域或每进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆