3

following piece of code is leaking memory even if no data is returned by database. could anyone shed some light on this. .net profiler application shows that the culprit is datatable

using (OleDbDataAdapter da = new OleDbDataAdapter("select * from external_message where status='P' and pendingthread=" + Thread.CurrentThread.ManagedThreadId, conn))
                {
                    DataTable dt = new DataTable();
                    da.Fill(dt);
                    if (dt.Rows.Count > 0)
                    {
                        DataRow dr = dt.Rows[0];
                        NotificationService.Logger.Write(Logger.RdvLogLevel.Debug, (uint)Thread.CurrentThread.ManagedThreadId, "GetInputs", "Received Message Id {0} Type {1}", dr["MessageId"].ToString(), dr.Field<string>("TargetType"));
                        return new DatabaseItem { connection = conn, dataRow = dr };
                    }
                    else
                    {
                        dt.Dispose();
                    }
                }
CharithJ
  • 46,289
  • 20
  • 116
  • 131
Mubashir Khan
  • 1,464
  • 1
  • 12
  • 17

3 Answers3

4

Probably below line cause memory leak. You have to Dispose Database Connections which holds some unmanaged data.

return new DatabaseItem { connection = conn, dataRow = dr };

If it leaking memory even if no data is return make sure you Dispose conn ? Always you have to dispose database connections.

CharithJ
  • 46,289
  • 20
  • 116
  • 131
  • "leaking memory even if no data is returned by database." – BrokenGlass Oct 05 '11 at 12:23
  • @BrokenGlass: Thanks for pointing that out. May be because not calling conn.Dispose() – CharithJ Oct 05 '11 at 12:26
  • connection is closed in the parent method. i am only returning this connection to reuse the already opened one. – Mubashir Khan Oct 05 '11 at 12:56
  • @MubashirKhan: I am not sure what's happening in the parent method. The point to keep in mind is, you must Dispose the connection when you don't want it. Closing is not enough. – CharithJ Oct 05 '11 at 12:58
  • DataTable is leaking memory not the connection. i dispose the connection in the parent mehtod. i am waiting to start a bounty and have reported it to microsoft to seek help https://connect.microsoft.com/VisualStudio/feedback/details/693522/datatable-memory-leak-in-windows-service http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5e62af05-37a9-4ea7-b223-124d957f236f – Mubashir Khan Oct 07 '11 at 05:19
0

I don't think that it is a leak. Such objects will consume resources until they are garbage collected. Your dt.Dispose() will provide a hint to the garbage collector that your object is no longer needed, but .Net will not clean it up until it feels like it.

You can prompt the garbage collector to run by calling GC.Collect(), but normally you should let .Net clean up after itself.

Joe Mancuso
  • 2,099
  • 1
  • 16
  • 17
  • i have a .net profiler application. it shows data whenever gc is called. the memory keeps growing and root references keep on increasing. this does not happen if i comment the above code. profiler shows that the finalizer of a ReaderWriterLock that was initialized in the cosntructor of datatable is stuck and there are lots of objects of this type in the gc queue that never get collected. – Mubashir Khan Oct 05 '11 at 12:55
  • Have you tried populating a DataSet in da.Fill and then grabbing the resulting DataTable? – Joe Mancuso Oct 05 '11 at 15:31
  • same code works fine in console application, but leaks memory windows service. kindly note that this code is written in separate thread – Mubashir Khan Oct 06 '11 at 10:39
0

[STAThread] on the Main function was causing problem. Removed it and everything is working fine now.

Mubashir Khan
  • 1,464
  • 1
  • 12
  • 17