不调用Delegate.EndInvoke可能会导致内存泄漏...一个神话? [英] Not calling Delegate.EndInvoke can cause memory leak... a myth?

查看:1380
本文介绍了不调用Delegate.EndInvoke可能会导致内存泄漏...一个神话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已经有许多讨论围绕这一点,每个人都倾向于同意,你应该始终调用Delegate.EndInvoke至prevent内存泄漏(甚至乔恩斯基特说对了!)。

There have been a lot of discussion around this and everyone tend to agree that you should always call Delegate.EndInvoke to prevent a memory leak (even Jon Skeet said it!).

我始终遵循这一方针没有质疑,但最近我实现了自己的AsyncResult类,看到这可能泄漏的唯一资源就是AsyncWaitHandle。

I always followed this guideline without questioning, but recently I implemented my own AsyncResult class and saw that the only resource that could leak is the AsyncWaitHandle.

(事实上它并没有真正流失,因为所用的WaitHandle的本土资源被封装在一个的SafeHandle其中有一个终结,这将增加pressure垃圾收集器的敲定队列但即便如此,一个良好的执行AsyncResult只会初始化对需求的AsyncWaitHandle ...)

(In fact it doesn't really leak because the native resource used by the WaitHandle is encapsulated in a SafeHandle which has a Finalizer, it will add pressure on the finalize queue of the garbage collector though. Even so, a good implementation of AsyncResult will only initialize the AsyncWaitHandle on demand...)

最好的办法知道是否有泄漏只是尝试一下:

The best way to know if there is a leak is just to try it:

Action a = delegate { };
while (true)
    a.BeginInvoke(null, null);

我跑了一会儿之间的记忆停留9-20 MB。

I ran this for a while and the memory stay between 9-20 MB.

让我们在Delegate.EndInvoke被调用比较:

Let's compare with when Delegate.EndInvoke is called:

Action a = delegate { };
while (true)
    a.BeginInvoke(ar => a.EndInvoke(ar), null);

通过这个测试,9-30 MG之间的记忆播放,奇怪吧? (可能是因为它需要更长的时间来执行时有一个AsyncCallback,所以将会有更多排队的代表在线程池)

With this test, the memory play between 9-30 MG, weird eh? (Probably because it takes a bit longer to execute when there is an AsyncCallback, so there will be more queued delegate in the ThreadPool)

你怎么认为?神话打掉?

What do you think... "Myth busted"?

P.S。 ThreadPool.QueueUserWorkItem是一百多Delegate.BeginInvoke更有效,它能够更好地使用它的火灾和放大器;忘了电话。

P.S. ThreadPool.QueueUserWorkItem is a hundred more efficient than Delegate.BeginInvoke, its better to use it for fire & forget calls.

推荐答案

我并运行一个小测试来调用一个Action委托并抛出一个异常里面。然后,我要确保我不会维持在同一时间运行的线程只有指定的数量淹没线程池,并填写线程池continously当删除通话已结束。这里是code:

I did run a little test to call an Action delegate and throw an exception inside it. Then I do make sure that I do not flood the thread pool by maintaining only a specified amount of threads running at one time and fill the thread pool continously when a delete call has ended. Here is the code:

 static void Main(string[] args)
    {

        const int width = 2;
        int currentWidth = 0;
        int totalCalls = 0;
        Action acc = () =>
            {
                try
                {
                    Interlocked.Increment(ref totalCalls);
                    Interlocked.Increment(ref currentWidth);
                    throw new InvalidCastException("test Exception");
                }
                finally
                {
                    Interlocked.Decrement(ref currentWidth);
                }
            };

        while (true)
        {
            if (currentWidth < width)
            {
                for(int i=0;i<width;i++)
                    acc.BeginInvoke(null, null);
            }

            if (totalCalls % 1000 == 0)
                Console.WriteLine("called {0:N}", totalCalls);

        }
    }

让它运行约20分钟,超过3000万后的BeginInvoke调用私有字节的内存消耗是恒定的(23 MB),以及句柄计数后。似乎没有泄漏被present。我已通过CLR阅读杰弗里Richters书C#,他指出,有内存泄漏。至少,这似乎不再是真正与.NET 3.5 SP1。

After letting it run for about 20 minutes and over 30 million BeginInvoke calls later the private byte memory consumption was constant (23 MB) as well as the Handle count. There seems no leak to be present. I have read Jeffry Richters book C# via CLR where he states that there is a memory leak. At least this seems no longer to be true with .NET 3.5 SP1.

测试环境: Windows 7的86 .NET 3.5 SP1 英特尔6600双核2.4GHz的

Test Environment: Windows 7 x86 .NET 3.5 SP1 Intel 6600 Dual Core 2.4 GHz

你的,   阿洛伊斯·克劳斯

Yours, Alois Kraus

这篇关于不调用Delegate.EndInvoke可能会导致内存泄漏...一个神话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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