Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not calling Delegate.EndInvoke can cause memory leak... a myth?

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!).

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.

(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);

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

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

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

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 is a hundred more efficient than Delegate.BeginInvoke, its better to use it for fire & forget calls.

like image 913
Jeff Cyr Avatar asked Nov 21 '09 01:11

Jeff Cyr


People also ask

What is the main cause of memory leaks?

A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.

Does function create memory leak?

No it does not cause memory leaks.

What causes memory leak C#?

If you have implemented a very long-running or infinite running thread that is not doing anything and it holds on to objects, you can cause a memory leak as these objects will never be collected. The fix for this is to be very careful with long-running threads and not hold on to objects not needed.

When can you tell that a memory leak will occur?

In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in such a way that memory which is no longer needed is not released. A memory leak may also happen when an object is stored in memory but cannot be accessed by the running code.


1 Answers

Whether or not it currently leaks memory is not something you should depend on. The framework team could, in the future, change things in a way that could cause a leak, and because the official policy is "you must call EndInvoke" then it's "by design".

Do you really want to take the chance that your app will suddenly start leaking memory sometime in the future because you chose to rely on observed behavior over documented requirements?

like image 173
Erik Funkenbusch Avatar answered Sep 21 '22 16:09

Erik Funkenbusch