Will there be an IDisposable memory leak if you do not use the using statement?

Will there be an IDisposable memory leak if you do not use the using statement?
And if so, can someone provide an example of a memory leak if there isn't a lot of code?

+2
source share
6 answers

A correctly written program that creates an instance of a type that implements IDisposable , and which, as you know, is not able to adequately clean after itself after a failure, must ensure that Dispose is called in this instance before abandoning it. Any program that cannot call Dispose on a type that is not exactly known does not work without it.

Although it would be nice if automatic finalization could take care of everything, this is a rather muddy cleanup mechanism. It does not give any guarantees regarding the sequence, thread context, timeliness or confidence in completion (when using deterministic cleaning, you can make sure enough that the program will not appear normal if the cleaning fails; when using finalization, the program may, as a rule, not even appear trying to clear an object).

Microsoft may IDisposable assume that every IDisposable class should be able to properly clean up after itself if it is left, but that is simply impractical. In many cases, for a class trying to clear after itself, leaving it will add enormous complexity and simply turn a broken program, which will have obvious problems that are easy to track down, into a broken program, which usually works except when the synchronization of the finalizer thread is relatively some other thread makes things fail in some unexpected and irreproducible way.

There are some types that, despite the implementation of IDisposable , are unconditionally safe for rejection, and there are some others that can be safely left under certain circumstances. It’s great to refuse such types in situations where it would be difficult to remove them (for example, because links are stored by several objects that are manipulated by various threads, and there is no good way that any particular object can know it when it is held by the last survivor link), provided that one of the documents gives reason to believe that such an action is safe and appropriate. However, this behavior is unacceptable in those cases when IDisposable objects of an unknown line are accepted.

+4
source

No, it will not leak. Ultimately, garbage collection will be directed to the removal of the object.

IDisposable allows the caller to free resources earlier.

Update

Like the state of @Servy and @Brian Rasmussen. A class that implements IDisposable must also implement a finalizer. This is a recommended practice. see http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx

+2
source

First of all, pay attention that IDisposable usually refers to external unmanaged resources 1 - for example. files, connections - and such leaks; The CLRs and memory used by such will still be accessed by the GC.

IDisposable defines a contract and represents a breaking change when adding or removing from a type. Any failure to comply with this contract may result in “undefined behavior”. The using construct is a tool that avoids the need to access the details of the Dispose call and edge with exceptions, but it is not part of the contract and is not required. Nevertheless, the contract remains unchanged, and any violations of this kind relieve themselves of all responsibility for the specified identification of "work correctly."

  • Some types that implement IDisposable will never lose resources; they cannot manage any external resources.
  • Some types that implement IDisposable do not follow the "best practice" of the finalizer implementation either; they will leak external resources if Dispose is not called.
  • Some types, such as those that implement the finalizer pattern, can only leak external resources in certain GC situations. That is, the finalizer may not be called soon enough. This condition may be too slow to be a problem in low-load scenarios, but lead to unexpected crashes in high-load scenarios.
  • Some types can lead to situations with poorly defined behavior and inconsistent state.

Do not break the contract.


1 The IDisposable type can also change some state in Dispose that does not use unmanaged resources: this is still covered under "incomprehensible behavior" if the contract is broken. In one case, when I used the IDisposable type, you must manage the Runtime Callable Wrapper (RCW) objects, even if they are technically “managed” by the runtime. See comment supercat for other situations.

+2
source

It all depends on your IDisposable .

The IDisposable template is basically a way to deterministically release managed (and unmanaged) resources, rather than waiting for the finalizer to complete for this object. If, for example, you open database connections, file descriptors, etc., you, of course, want these resources to be released or otherwise cleared "on demand", so they do not prevent you from re-accessing them in the other place. This is the main use case for the Dispose pattern.

So, will it be a memory leak? Again, it depends - it’s very likely if you use IObervable<T> subscriptions, since in a sense they are not triggered event handlers (I simplify it here a lot). Can you cause a memory leak if you do not close this SqlConnection ? Not by the strictest definition of “memory leak,” since the connection eventually closes (say when your application terminates, or the connection object is finally assembled and completed), but I think I can say all this by saying:

"ALWAYS delete your IDisposables"

EDIT: @Servy is absolutely right - in my SqlConnection example, I believe that the finalizer automatically closes the connection, but this is NOT a guaranteed behavior for IDisposables in general - always Dispose!

+1
source

using statement only syntactic sugar

  using(var resource = expression) statement 

which translates something you like

 { var resource = expression; try { statement; } finally { [if(resource!=null)]((IDisposable)resource).Dispose(); } } 

If the utility is implemented correctly, a memory leak will not occur. GC calls (not deterministic) Finalizer , which calls the Dispose method.

+1
source
Operator

Using calls the Dispose method of the object at the end of the block.

you can use the following example to get the same result:

  obj a = new obj(); // Assuming obj : IDisposable try { // Your code here } finally { if (a != null) { a.Dispose(); } } 
0
source

All Articles