Clearing ODBC DSN in C # .NET
I am using C # and OBDC DSN to connect to Paradox database. I seem to be experiencing a memory leak if I open and close every connection.
My code is basically:
csb.Dsn = "DNSName";
OdbcConnection con = new OdbcConnection(csb.ConnectionString);
con.Open();
OdbcCommand comm= new OdbcCommand("SELECT * FROM Tabl", con);
OdbcDataReader reader= null;
try
{
reader= comm.ExecuteReader();
for (int count = 0; (count < 5 && reader.Read()); ++count)
{
//Read
}
}
finally
{
if (reader!= null)
{
reader.Close();
reader.Dispose();
}
if (comm!= null)
{
con.Close();
con.Dispose();
OdbcConnection.ReleaseObjectPool();
GC.Collect();
comm.Dispose();
}
}
Any ideas or suggestions?
Update 1
I changed it to use using statuses, still flows.
source to share
using (var connection = new OdbcConnection (csb.ConnectionString)) { connection.Open (); using (var command = new OdbcCommand ("SELECT * FROM Tabl", connection)) using (var reader = command.ExecuteReader ()) { for (var count = 0; (count <5 && reader.Read ()); ++ count) { // Read } } } OdbcConnection.ReleaseObjectPool ();
There is no memory leak in the above code unless it is created in the "// Read" exception clause. GC.Collect shouldn't be used in production ever; it will most likely not help in any way, and may actually interfere with the GC as it is self-tuning. Grab a profiler (or free trial) like ANTI Memory Profiler and see what's hanging on your objects.
Don't trust Windows Task Manager to show if you have a leak . Be sure to use a profiler for this purpose.
source to share
Try to establish connection, command and reader within operators using
.
Then call OdbcConnection.ReleaseObjectPool();
at the end.
Note. Garbage collection can take several minutes. To prove that there is no leak, you can call GC.Collect()
three times in a row [three times to clean objects across all three generations].
Don't leave GC.Collect()
in working code, but because it can be a big performance hit.
source to share
How did you find the leak? Sometimes memory usage spikes up in Task Manager and immediate release can happen because the GC doesn't fire directly or you have a connection pool or handle that hasn't been released in a managed environment yet. I suggest you use a memory profiler like the ANTS Mem Profiler suggested by Travis. You can get trial version, otherwise use Microsoft CLRProfiler base version.
Another good measure is to load the process so that it runs longer during the profiling process, so if there is a problem it will be clearly shown. The easiest way is to put a loop around it to tell you to run over 1000 times or more. You can also use Performance Monitor to monitor portions of the interest count and see how they are tracked at runtime.
source to share