简体   繁体   中英

Consequences of not using using() DB connections?

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 (ie 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. Eg, 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 (ie 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM