Reputation: 43
I have built a wrapper DLL for a database that gives me an object API layer for my database. Where I am having issues is that the Garbage Collector in VB.net doesn't seem to be cleaning up the mess when I destroy the objects. I am relatively certain that I have done everything to clean up the object, including implementing the IDispose interface on every object to destroy everything.
Where things get ugly is when I instantiate the object, I do a database read and populate the object based on it's corresponding entry in the database. This works well, however, when I iterate through the creation and destruction of 1000's and 1000's of these objects, the memory just keeps ramping up.
Then it occurred to me: Could it be that my objects won't clean up because I am using a shared ODBC database reference inside my objects? would that keep my objects alive despite my best efforts?
For example: (note: clsSharedConfig.g_objDatabaseConn is a shared ODBCConnection instance)
Dim cmd As New OdbcCommand("SELECT * FROM FILES WHERE CID = " & p_lngID, clsSharedConfig.g_objDatabaseConn)
Dim data As OdbcDataReader
Try
cmd.CommandType = CommandType.Text
data = cmd.ExecuteReader()
Can anyone offer any other reason I am having this happen? I don't want to have to resort to shoving GC.Collect statments in everywhere to keep this under control!
Thanks,
Andrew
Upvotes: 0
Views: 705
Reputation: 43
So, I tried your suggestions (thanks BTW!), but alas, no change...
Then, just for a larf, I was looking around in the application settings for my DLL. I noticed that for some dumb/unknown reason, I had COM compatibility turned on.
So, I unchecked that, on the premise that I didn't NEED COM compatibility and that was just muddying the waters in finding a solution. As soon as I did, and I re-ran it, The memory leak was GONE!
Seriously? that was IT? I need someone to 'splain that one to me slowly, perhaps using hand puppets.
A memory profiler confirmed that my leak was in unmanaged memory.
that's 2 days Im not getting back...
Andrew
Upvotes: 0
Reputation: 2901
You have to close the reader to free up resources. See below
Private Sub CmdReaderSample(ByVal cn As OleDbConnection, ByVal strCmd As String)
Dim cmd As OleDbCommand = New OleDbCommand(strCmd, cn)
cmd.CommandType = CommandType.Text
Dim objReader As OleDbDataReader = cmd.ExecuteReader
Try
'read some stuff objReader.Read()
Finally
objReader.Close()
End Try
End Sub
Also check when your objects are loaded from reader, you maybe keeping a reference there as well. Memory leaks are better chased by using memory profiler like Ants memory profiler
Upvotes: 1
Reputation: 46340
Have you tried just instantiating a new connection object each time? the .net framework will handle the actuall connection pooling under the hood, so I'm not sure that trying to share that object helps you alot anyhow.
Upvotes: 0