VS 2010 Beta Code Analysis is advising me to always dispose WCF Service Clients and Data Contexts for LINQ to SQL. Is this advisable? I assume this will eventually happen regardless. What are the pros/cons of doing so implicitly or not at all?
With anything that is IDisposable, it is your job to ensure it gets cleaned up promptly, to close open resources etc (connections, etc). So in short, yes. Finalizers only happen when GC kicks in, which can be a long time - and doesn't allow for the best pooling use etc.
Note however that WCF has a history of dodgy Dispose() implementations, making just using a bit hit-n-miss (you can lose the actual exception). Of course, it is also recommended to use WCF via async methods, which again makes it hard to use using; you'll often need to keep a reference and call Dispose() explicitely in the IO callback.
Re your comments; a few examples:
SqlConnection: if you leave this hanging around (open) you prevent it reusing the connection from a pool; you can ultimately saturate the available connections this way, breaking your app
GDI: IIRC, VS2005 itself (or 2003?) had a bug where an undisposed GDI object; GDI objects don't take much memory, so it didn't trigger GC, but it ran out of available handles and broke (this is a common bug in user code too, but more famous in an IDE)
fail to dispose something like a FileStream: you've blocked your file system
fail to dispose a TransactionScope and you've caused db (etc) blocking
Related
Uses of "using" in C# has a nice explanation of the utilities of the using feature.
.Net has its garbage collector. How does it handle the lack of a dipose()?
Specifically for DB connections, statements and resultsets, is it required a using() for each of them? What happens if they are left behind with no using(), dispose() and neither close()?
Update: the context is web applications, therefore there may be thousands of simultaneous users, each with his own connection/stmt/rs and the app will never be closed.
Since using is a shorthand for calling Dispose, you could imitate it with try/finally. So the real question is what's the consequence of not calling Dispose at all.
Although C# has garbage collection which would eventually release resources most of the time, you want the release of critical resources to happen as soon as you are done with them. If you use using or the equivalent try/finally, the resources would be released quickly. If you let the garbage collector to release the resources for you, your program may be starved of resources while they are "in custody" of GC (i.e. your program is no longer using them, but GC has not released them yet). Moreover, since GC offers no hard guarantee of running finalizers, some resources may not get released explicitly until your program ends, which may cause resource starvation of other processes.
You don't know when .net's garbage collector is called and run, so it's allowing you to do it yourself when you don't need it. So, when your code gets out of using() it's dispose object used in using() instead of waiting for GC to run on its own schedule.
If you don't use with DB connection, then GC will dispose it on its own way based on criteria of algorithm it's implementing. It might get too late(in terms of computer clock) to sweep it.
Garbage collector is a background thread which doesn't run every millisecond. It has specific schedule and its own algorithm which tends it to work on a specific time. E.g., some GC algorithms check for objects having no references then they sweep those objects when GC runs.
Specifically for DB connections, statements and resultsets, is it
required a using() for each of them? What happens if they are left
behind with no using(), dispose() and neither close()?
Actually the worst consequence of a memory leak is holding some memory until you restart the PC. However in this case probably the worst consequence is leaking memory until you restart the application.
If memory growth increases up to where GC cannot clean any longer, in fact if Gen 2 of Small Object Heap is overflow (Large object heap also can overflow), it will throw out of memory exception and close the application.
.Net has its garbage collector. How does it handle the lack of a
dipose()?
All the standard database connection related classes have implement Dispose and Finalize methods properly. Generally there are unmanaged resources in those classes. Unmanaged resources are the resouces (eg: file handlers, database connection handlers and etc) which could cause worse memory leaks that may hold memory until you restart the PC. However, that's where GC's finalization comes handy. If you don't call the Dispose for such Disposable object, garbage collector will execute the Finalize method(if there is a ~destructor) and clear unmanaged resources.
That's the reason why it is required to implement IDispose Pattern properly Dispose and Finalization as required. Finalization is required only if it has Unamanged resources.
The most likely consequence of failing to promptly Dispose database objects is that the program will ask a database server to open a database connections on its behalf with a promise that it will tell the server when they are no longer needed (i.e. close them), but may leave the connections open for quite awhile after they're no longer needed. Such behavior may increase the number of connections the database server will need to keep open simultaneously. Depending upon the server, there may be no consequences, or the extra connections may impair performance, or they may cause some connection requests to get needlessly denied.
Although .NET will try to ensure that database servers will get notified when database objects are abandoned, even if Dispose is not called, the code which uses database objects will generally know when it will no longer need them, long before .NET can determine that they're abandoned. Note also that while some .NET database-related libraries may keep connections open for a little while after a Dispose (so that if code needs the database again it can resume using the earlier connection) such libraries may use timers to limit how long connections are maintained in expectation of further use, rather than depend upon the garbage-collector (which might go a very long time without noticing that an object has been abandoned).
I have seen examples where someone is doing:
IDbConnection db = new MySqlConnection(conn);
var people = db.Query<People>("SELECT * FROM PEOPLE").ToList();
or is the above a bad practice and should all queries be put in using statements like so:
using (var db = new MySqlConnection(conn))
{
var people = db.Query<People>("SELECT * FROM PEOPLE").ToList();
}
As others have correctly noted, the best practice in general is to use using any time an object implements IDisposable and you know that the lifetime of the object is going to be short -- that is, not longer than the duration of the current method. Doing so ensures that scarce operating system resources are cleaned up in a timely manner. Even if an object's disposal is "backstopped" by its finalizer, you don't want to be in a situation where, say, you have a lock on a file or database or something that is not going to be released until the finalizer runs several billion nanoseconds from now.
However I would temper that advice by saying that there are a small number of types that implement IDisposable for reasons other than timely disposal of unmanaged resources. In some very specific cases you can safely skip the using. However, it is almost never wrong to use using, even when it is not strictly speaking necessary, so my advice to you is to err on the side of caution and over-use, rather than under-use using.
Dapper doesn't have a view on this; what you are using here is the database connection. If you have finished with the connection: you have finished with the connection. Basically, yes, you should probably be using using.
The main purpose use of using statments is to release unmanaged resources.When an object is no longer used The garbage collector automatically releases the memory allocated to it but sometimes the garbage collector does not release resources such as files, streams or db connection like in your example.
Think of it of a way to explicitly dispose objects rather than leave it up to the compiler so you can say it's better practice.
In my experience with Sql Server and Oracle (using the ODP.Net drivers and the MS drivers), you need to use using around Connections, Commands and Transactions or you will soon exhaust your connection pool if you do anything but the simplest database interaction in a production environment (the connection pool is typically ~50 - 200 connections).
You may not notice the behaviour in a development environment because debug = a lot of restarts, which clears the pool.
As Eric Lippert above said, it is good practice in general to use using around IDisposable objects.
In practice, you can skip "using" on Parameters for SqlServer and Oracle.
Do I have to use a using statement to dispose immediately even in a method? Or will the ending of the method cause an automatic Dispose of all local variables including graphics?
(I’m asking this because I’ve seen examples that have Dispose calls at the end of methods, and wanted to know if that’s really necessary.)
Thanks.
Yes, you do. Going out of scope does not do anything; it does not call Dispose(), it does not garbage-collect, it does not call a finalizer.
If the type is IDisposable, then yes. It is your job to tidy up after yourself (assuming that the object is actually "done with" at this point).
Possible side-effects of not doing this:
files get left open and cause access-exceptions (FileStream)
connections get left open and cause pool saturation (DbConnection)
unmanaged handles get saturated and cause resource starvation (any winforms/etc)
transactions get left open and cause blocking (TransactionScope / DbTransaction)
etc
basically, bad things.
Furthermore, in most cases where you see Dispose() at the bottom of the method, a using would be preferable. There are some cases where that isn't possible (fields on an object, for example), but the point remains: it sounds like those are bad examples.
You don't ever have to dispose of an object. But if you want to release unmanaged resources earlier rather than whenever the GC gets around to it (which is when it processes the fReachable queue) then yes you should since the scope of of a method does not determine when a disposable object's finalize will be called.
For more you might want to read Jeffrey Richter's Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
As delnan noted if there's a hard limit to the resources you're using you're much more likely to impacted if you let it get reclaimed by the GC rather than calling Dispose. DB connections are a good example of this kind of reasource and is certainly the reason why the NumberOfReclaimedConnections performance counter got created.
Yes, use using. It is a great statement.
Actually if you don't call Dispose (either manually or by using using), you can end up in a situation where your managed memory is stil quite empty, but unmanaged resources are depleted. Eventually it can cause a deadlock because other objects or other processes will wait for your unmanaged resources and you will wait for them. (Garbage collector won't run, because managed memory still won't be full.)
So please call Dispose as soon as you can. Once you don't need an object which has got that method defined, call it.
Scenario
Lets say that I've decided I really need to call GC.Collect();
What do I need to do to ensure that an object is prepared to be garbage collected appropriately before I actually call this method?
Would assigning null to all properties of the object be enough? Or just assigning null to the object itself?
If you really need to know why.....
I have a distributed application in WCF that sends a DataContract over the wire every few seconds, containing 8 Dictionaries as DataMembers.
This is a lot of data and when it comes into the Client-side interface, a whole new DataContract object is created and the memory usage of the application is growing so big that I'm getting OutOfMemory Exceptions.
Thanks
EDIT
Thanks for all the comments and answers, it seems that everyone shares the same opinion.
What I cannot understand is how I can possibly dispose correctly because the connection is open constantly.
Once I've copied the data over from the incoming object, I don't need the object anymore, so would simply implementing IDisposable on that DataContract object be enough?
My original problem is here - Distributed OutOfMemory Exceptions
As long as nothing else can see the object it is already eligible for collection; nothing more is required. The key point here is to ensure that nothing else is watching it (or at least, nothing with a longer lifetime):
is it in a field somewhere?
is it in a variable in a method that is incomplete? (an infinite loop or iterator block, perhaps)
is it in a collection somewhere?
has it subscribed to some event?
it is captured in a closure (lambda / anon-method) that is still alive?
I genuinely doubt that GC.Collect() is the answer here; if it was eligible it would have already been collected. If it isn't elgible, calling GC.Collect() certainly won't help and quite possibly will make things worse (by tying up CPU when nothing useful can be collected).
You don't generally need to do anything.
If the object is no longer referenced then it's a candidate for collection. (And, conversely, if the object is still referenced then it's not a candidate for collection, however you "prepare" it.)
You need to clean up any unmanaged resources like database connections etc.
Typically by implementing IDisposable and call Dispose.
If you have a finalizer you should call GC.SuppressFinilize.
The rest is cleaned up by the garbage collector.
Edit:
And, oh, naturally you need to release all references to your object.
But, and here is this big but. Unless you have a very very special case you don't need to call GC.Collect. You probably forgets to release some resources or references, and GC.Collect won't help you with that. Make sure you call Dispose on everything Disposable (preferably with the using-pattern).
You should probably pick up a memory profiler like Ants memory profiler and look where all your memory has gone.
If you have no more direct reference to an object, and you're running out of memory, GC should do this automatically. Do make sure you call .Dispose() on your datacontext.
Calling GC.Collect will hardly ever prevent you from getting OutOfMemory exceptions, because .NET will call GC.Collect itself when it is unable to create a new object due to OOM. There is only one scenario where I can think of and that is when you have unreferenced objects that are registered in the finalizable queue. When these objects reference many other objects it can cause a OOM. The solution to this problem is actually not to call GC.Collect but to ensure that those objects are disposed correctly (and implement the dispose pattern correctly when you created those objects).
Using GC.Collect in general
Since you are trying to get rid of a very large collection, it's totally valid to use GC.Collect(). From the Microsoft docs:
... since your application knows more about its behavior than the runtime does, you could help matters by explicitly forcing some collections. For example, it might make sense for your application to force a full collection of all generations after the user saves his data file.
"Preparing" your objects
From the excellent Performance Considerations for Run-Time Technologies in the .NET Framework (from MSDN):
If you keep a pointer to a resource around, the GC has no way of knowing if you intend to use it in the future. What this means is that all of the rules you've used in native code for explicitly freeing objects still apply, but most of the time the GC will handle everything for you.
So, to ensure it's ready for GC, Make sure that you have no references to the objects you wish to collect (e.g. in collections, events, etc...). Setting the variable to null will mean it's ready for collection before the variable goes out of scope.
Also any object which implements IDisposable should have it's Dispose() method called to clean up unmanaged resources.
Before you use GC.Collect
Since it looks like your application is a server, using the Server GC may resolve your issue. It will likely run more often and be more performant in a multi-processor scenario.
The server GC is designed for maximum throughput, and scales with very high performance.
See the Choosing Which Garbage Collector to Use within Performance Considerations for Run-Time Technologies in the .NET Framework (from MSDN):
I'd like to know when i should and shouldn't be wrapping things in a USING block.
From what I understand, the compiler translates it into a try/finally, where the finally calls Dispose() on the object.
I always use a USING around database connections and file access, but its more out of habit rather than a 100% understanding. I know you should explicity (or with a using) Dispose() objects which control resources, to ensure they are released instantly rather than whenever the CLR feels like it, but thats where my understanding breaks down.
Are IDisposables not disposed of when they go out of scope?
Do I only need to use a USING when my object makes use of Dispose to tidy itself up?
Thanks
Edit: I know there are a couple of other posts on the USING keyword, but I'm more interested in answers relating the the CLR and exactly whats going on internally
Andrew
No, IDisposable items are not disposed when they go out of scope. It is for precisely this reason that we need IDisposable - for deterministic cleanup.
They will eventually get garbage collected, and if there is a finalizer it will (maybe) be called - but that could be a long time in the future (not good for connection pools etc). Garbage collection is dependent on memory pressure - if nothing wants extra memory, there is no need to run a GC cycle.
Interestingly (perhaps) there are some cases where "using" is a pain - when the offending class throws an exception on Dispose() sometimes. WCF is an offender of this. I have discussed this topic (with a simple workaround) here.
Basically - if the class implements IDisposable, and you own an instance (i.e. you created it or whatever), it is your job to ensure that it gets disposed. That might mean via "using", or it might mean passing it to another piece of code that assumes responsibility.
I've actually seen debug code of the type:
#if DEBUG
~Foo() {
// complain loudly that smoebody forgot to dispose...
}
#endif
(where the Dispose calls GC.SuppressFinalize)
"Are IDisposables not disposed of when
they go out of scope?"
No. If the IDisposable object is finalizable, which is not the same thing, then it will be finalized when it's garbage collected.
Which might be soon or might be almost never.
Jeff Richter's C#/CLR book is very good on all this stuff, and the Framework Design Guidelines book is also useful.
Do I only need to use a USING when my
object makes use of Dispose to tidy
itself up?
You can only use 'using' when the object implements IDisposable. The compiler will object if you try to do otherwise.
To add to the other answers, you should use using (or an explicit Dispose) whenever an object holds any resources other than managed memory. Examples would be things like files, sockets, database connections, or even GDI drawing handles.
The garbage collector would eventually finalise these objects, but only at some unspecified time in the future. You can't rely on it happening in a timely fashion, and you might have run out of that resource in the meantime.