问题
In the comments to an answer I wrote we had a discussion about memory leaks and IDisposable where we didn't come to any real conclusion.
A class that handles unmanaged resources likely implements IDisposable. If ignore that and neither call Dispose nor wraps the object in a using - will that lead to the unmanaged resource being leaked? Or will it be properly cleaned up when the GC collects the object?
We can assume that the class handling the unmanaged resource has a correct implementation of IDisposable, including finalizer etc.
回答1:
It will not cause a memory leak. In fact, Dispose has absolutely nothing to do with memory management.
It will create a resource-leak. And while the GC will usually clean it up, this could be too infrequent and too late.
Omitting Dispose (using) can slow down or even crash your App. In the case of file resources or Db connections it can even cause problems in other applications.
回答2:
I will not cause managed memory leaks. It can cause leaks in referenced unmanaged code. But it's worse than that: memory on modern systems is plentiful enough that you can often get by for a while with a bad leak. Witness Mozilla Firefox: it used to (does it still?) leak like a sieve, and millions were happy to use it.
The bigger problem is other resources that may have nothing to do with memory at all. Examples include database connections, system I/O handles, socket handles, file handles, and the like. These are all items where you can easily create denial of service situations on your own system if you aren't careful to use IDisposable properly.
回答3:
Just to add a little to Henk and Joel's answers
What you've described happens quite often on DB Connections specifically. Enough that the ADO.NET Performance counter NumberOfReclaimedConnections got added. This counter tracks...
The number of connections that have been reclaimed through garbage collection where Close or Dispose was not called by the application. Not explicitly closing or disposing connections hurts performance.
The performance hit is usually a longer then necessary wait for a connection to be freed up. This can also result in timeouts on the connection, not a memory problem.
回答4:
If an IDisposable object has a finalizer that de-allocates unmanaged memory then the memory will be free when the finalizer is called (after it is marked for collection by the GC and placed in the finalizer queue), but if there isn't any finalizer and Dispose() is never called, then memory can be leaked and only re-claimed when the process terminates.
回答5:
Failing to call IDisposable on objects which subscribe to events from longer-lived objects will extend the memory-allocation lifetime of the subscriber to be extended to that of the publisher. If there is no upper bound to the number of subscribers that may be attached and abandoned during a publisher's lifetime, this will constitute an unbounded memory leak.
回答6:
The big issue is when the GC runs.
Take the following class
class GcTest
{
private Stopwatch sw = new Stopwatch();
public GcTest()
{
sw.Start();
}
~GcTest()
{
sw.Stop();
Console.WriteLine("GcTest finalized in " + sw.ElapsedMilliseconds + " ms");
}
}
Put a breakpoint on the Console.WriteLine if you like.
Create an empty windows forms app, and in the form load event just instantiate a new GcTest
private void Form1_Load(object sender, EventArgs e)
{
var gcTest = new GcTest();
}
Run your application and wait for the finalizer to run.
Most likely it won't run until you close your application.
回答7:
To my knowledge the GC will not call Dispose. You have to call it yourself explicitly or use using. So the answer is: Yes, if the class handles unmanaged resources, which are released in Dispose, your class will leak, if you don't call Dispose.
来源:https://stackoverflow.com/questions/6865330/will-ignoring-idisposable-cause-memory-leaks