Memory leak in .NET.

What are all the possible ways to troubleshoot memory leaks in .NET?

I know two:

Example:

// Causes Leaks Label label = new Label(); this.Controls.Add(label); this.Controls.Remove(label); // Correct Code Label label = new Label(); this.Controls.Add(label); this.Controls.Remove(label); label.Dispose(); 

Refresh . The idea is to list common errors that are not too obvious (like above). Usually, the concept is that memory leaks are not a big problem due to the garbage collector. It doesn't seem to be in C ++.




Great discussion guys, but let me clarify ... by definition, if there is no object reference in .NET, it will be garbage collection at some point. Therefore, this is not a way to cause a memory leak.

In a managed environment, I will consider a memory leak if you had an inadvertent reference to any object you don't know about (here are two examples in my question).

So, what are the different possible ways of a memory leak?

+20
optimization memory-leaks
Aug 21 '08 at 16:11
source share
14 answers

Block the finalizer flow. No other objects will be garbage collected until the finalizer stream is unlocked. Thus, the amount of memory used will grow and grow.

Further reading: http://dotnetdebug.net/2005/06/22/blocked-finalizer-thread/

+5
Aug 23 '08 at 8:17
source share

It really doesn't cause leaks, it just does more work for the GC:

 // slows GC Label label = new Label(); this.Controls.Add(label); this.Controls.Remove(label); // better Label label = new Label(); this.Controls.Add(label); this.Controls.Remove(label); label.Dispose(); // best using( Label label = new Label() ) { this.Controls.Add(label); this.Controls.Remove(label); } 

Leaving disposable components lying around like this is never a problem in a managed environment such as .Net, which is most of what controls the tools.

You, of course, slow down the application. But you will not leave a mess for anything else.

+21
Aug 21 '08 at 16:21
source share

It is not possible to provide an exhaustive list ... this is very similar to the question: "How can you get wet?"

However, make sure that you call Dispose () on everything that implements IDisposable, and make sure that you implement IDisposable for any types that consume unmanaged resources of any type.

From time to time, run something like FxCop on your code base to help you comply with this rule - you will be surprised at how deeply some disposable objects burrow into the application framework.

+14
Aug 21 '08 at 16:13
source share

Setting the GridControl.DataSource property directly without using an instance of the BindingSource class ( http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx ).

This caused leaks in my application, which took me quite a while to track with the profiler, and eventually I found this error report, to which Microsoft responded: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback .aspx? FeedbackID = 92260

It's funny that in the documentation for the BindingSource class, Microsoft is trying to pass it as a well-designed class, but I think they just created it to fix a fundamental leak in relation to currency managers and linking data to network controls.

Keep track of this, I'm betting that because of this, leaking apps are absolutely loaded there!

+14
Nov 25 '08 at 20:34
source share

Exceptions to Finalize (or Dispose calls from Finaliser) methods that prevent unmanaged resources from being properly allocated. The usual one is because the programmer assumes which objects will be deleted and tries to free peer objects that have already been deleted, which leads to an exception, and the rest of the Finalize / Dispose from Finalize method is not called.

+4
Aug 21 '08 at 16:38
source share

I have 4 additional elements that can be added to this discussion:

  • Termination of threads (Thread.Abort ()) that created user interface controls without proper preparation for such an event can cause memory to be used expectantly.

  • Accessing and clearing unmanaged resources through Pinvoke can lead to a memory leak.

  • Change large string objects. Not necessarily a memory leak when it goes out of scope, the GC will take care of this, however, in terms of performance, your system may suffer if large lines change frequently, because you cannot really depend on the GC to ensure it is minimal.

  • Creating GDI objects often to execute a custom drawing. If GDI execution often runs, reuse one gdi object.

+3
Jul 27 '10 at 18:25
source share

Are you talking about unexpected memory usage or actual leaks? The two cases you have indicated are not exactly leaks; these are cases where objects stick for longer than anticipated.

In other words, these are links that the person calling them memory leaks did not know or did not forget.

Edit: either they are actual errors in the garbage collector or unmanaged code.

Edit 2: Another way to think about this is to always ensure that external links to your objects are released appropriately. External code means out of your control. In any case, when this happens, this is the case when you can "console" the memory.

+2
Aug 21 '08 at 16:18
source share

Calling IDisposable every time is the easiest place to run, and certainly an effective way to capture all the bad results of a memory leak in the code base. However, this is not always enough. For example, it is also important to understand how and when managed code is generated at run time, and that after assemblies are uploaded to the application domain, they are never unloaded, which can increase the size of the application.

+2
Aug 21 '08 at 16:19
source share

To prevent .NET memory leak:

1) Use the "using" (or "try-finally") construct whenever an object with an "IDisposable" interface is created.

2) Make class ids' if they create a stream, or add an object to a static or durable collection. Remember that C # 'event' is a collection.

Here is a short article on memory leak prevention tips .

+2
Jun 25 '10 at 20:20
source share
  1. Saving links to objects that you no longer need.

Repeat the other comments - one way to ensure that Dispose will be called using ... when the code structure allows this.

+1
Nov 13 '09 at 1:20
source share

For me it was unexpected:

 Region oldClip = graphics.Clip; using (Region newClip = new Region(...)) { graphics.Clip = newClip; // draw something graphics.Clip = oldClip; } 

Where is a memory leak? That's right, you should have oldClip ! Since Graphics.Clip is one of the rare properties that returns a new one-time object every time getter is called.

+1
Jun 25 '10 at 20:30
source share

Tess Fernandez Has excellent blog posts about finding and debugging memory leaks. Laboratory 6 Laboratory 7

+1
Jul 28 '10 at 13:46 on
source share

Many things that can cause a memory leak in unmanaged languages โ€‹โ€‹can still cause a memory leak in managed languages. For example, poor caching policies can lead to memory leaks.

But, as Greg and Danny said, there is no exhaustive list. Anything that may lead to storing memory after its useful life may cause a leak.

0
Aug 21 '08 at 16:18
source share

Disabled threads will never issue roots. Obviously, you could argue that deadlock is a big problem.

A blocked finalizer thread will prevent all remaining finalizers from starting and thus prevent the recovery of all completed objects (since they are still rooted in a free list).

On a multiprocessor machine, you can create objects to be finalized faster than the finalizer thread can run finalizers. While this continues, you will โ€œleakโ€ into memory. It is probably not very likely that this will happen in the wild, but it is easy to reproduce.

The heap of large objects does not compact, so you can leak memory through fragmentation.

There are several objects that must be released manually. For example. delete objects without rent and assemblies (you must unload AppDomain).

0
Nov 25 '08 at 20:08
source share



All Articles