Thursday, March 22, 2012

Major problems with connection object ADO.NET and garbage collection

We have a huge portal app written in VB.NET (ASP.NET)
We create and destroy connections all the time, calling .Close and .Dispose on the connection. Loads of connections...thousands...we have a user base of about 10,000.
However the garbage collection has problems in dealing with unmanaged resources, ie connection objects. This isn't a problem 99.99% of the time. BUT once in a while the connection pool runs out of memory for the connections :(

This is a documented "feature" of .NET and even MS say that you should use C# to create the DB backend.

Has anyone come across this before?

WokaWell in C# you have use of the Using statement which allows for proper disposal of any object that implements IDisposal (database objects for example).

using (SqlConnection connection = new SqlConnection(connectionString)
using (SqlCommand command = new SqlCommand())
{
...
command.ExecuteReader();
} //both objects declared in the using statements above are now guaranteed to be disposed

To me it sounds there is some lazy connection coding going on. I've also seen people pass datareaders out of methods that retrieve data instead of populating an array or datatable and returning the datatable allowing the datareader to dispose.

try
connection = new SqlConnection();
reader = command.ExecuteReader();
catch
finally
if Not reader is Nothing
If Not reader.IsClosed
reader.Close()
End If
if Not connection Is Nothing
If Not Connection.State = Closed 'sorry don't remember the constant
Connection.Close()

end try
To me it sounds there is some lazy connection coding going on.
I can assure you there isn't ;)
It looks like we will have to use c# for this :(
MS is aware of this problem, and it says "tuff"...use c#
What?! This makes VB.NET rubbish for enterprise level apps :(

WOka
I wasn't aware of any problem...

There is far amount of confusion out there on object disposal of unmanaged resources... and a few reputable blogs point this out.

It appears that on some resources such as a TextWriter, calling Close calls Dispose... whereas on the SqlConnection object, calling Close does not call Dispose.

Furthermore, Dispose on a SqlConnection object does not actually dispose of the underlying connection... it still exists in the connection pool.
Its simply a pattern that should be followed in case the underlying plumbing changes in the future.

Supposedly, IDisposable was plugged into the framework toward the end which is why there are some discrepancies between behaviors of objects that implement Close and Dispose (textwriter vs SqlConnection example).

You can use the ILDASM to compare the generated code between VB and C# code and I have written VB.NET code that does the same thing as the C# using statement (which is to make a call to Dispose after the object is done being used - which remember doesn't do anything anyway in data access.)

0 comments:

Post a Comment