datagridview datasource and memory problems

ok I've got the problem that my application is using more and more memory when it's being run for a long period of time and I've narrowed it down to a specific statement that is eating a chunk of my memory each time it is called.

I have a function, For this example I'll just call it funct(). and this is how it is being called:

GC.Collect();

Console.WriteLine("start: " +GC.GetTotalMemory(true).ToString());

funct();

GC.Collect();

Console.WriteLine("end: " +GC.GetTotalMemory(true).ToString());

These events are called when I press a button on the main form. Basically what I'm trying to do here is trying to find out where the memory is being allocated. The reason I place my test code in the function is so that any temporary variable I use get garbage collected properly. In funct() is the following code:

datatable a = database.getTable("SELECT * FROM blah;");

GC.Collect();

Console.WriteLine("middle: " +GC.GetTotalMemory(true).ToString());

maingrid.datasource = a;

the gettable function simply returns a datatable, and maingrid is a datagridview. in the console, start: and end: have the same number beside it (if not, then very very close). When I take out the last line out of funct, then start and end are always the exact same. if I have the last line in, then end is roughly 100,000 bytes bigger. The table has 10 rows and 8 columns.

every time this function is run, 100,000 bytes are allocated, this function is run rounghly every minute causing the application too reach hundreds of megs in only a few days of running.

My question is: is this the proper way to update a datagridview? should it be allocating all this memory and not freeing it? I'm kinda stuck here...

[2849 byte] By [Simoyd] at [2007-12-28]
# 1

I've been able to get rid of most of the memory leaking by persisting my datatable. Rather than creating a new table each time, I simply do datatable.clear() and then dataadaptor.fill(datatable) to fill it again.

I'm curious if this is the correct way to do this. Even if I set the datagridview.datasource to a bindingsource, it still allocated 100k every time I set the bindingsource.datasource to a new table. Am I missing something?

I've since downloaded .net memory profiler and and trying to track down the smaller memory leaks. The datarows accessed by the datagridview aren't being deallocated when I change the datasource.... how the hell do I get rid of them? they aren't appearing in the row list and they aren't being displayed on the screen, but .net memory profiler says there are 10 new rows and 0 deleted everytime.. I am clearing the datatable... but I'm not sure what to do...

Simoyd at 2007-9-4 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 2

OK, I've reproduced my problem outside my application in a small function. All you need to do is create a new windows application, (default name: "WindowsApplication1"), drag a button, textbox and datagridview onto the form and paste the code below replacing the form code.

The textbox will display the current memory usage. Press the button to induce the error. Read through the code to see what I'm doing wrong.

.net memory profiler says that 4 new datarows are being allocated every time but only 3 get deallocated. With further inspection there seems to be a list<datarow> class that is pointing to the first row that get's put into the table thus giving it 4 references. the other rows only have 3 references to them. When the table is cleared, the first row fails to de dealocated even though it's not referenced by the datatable. The datagridview is holding onto it somewhere.

In my oppinion this is a bug in the datagridview, but I would like to know if there is another way to do what I'm trying to do without leaking memory all over the place!

Any help would be greatly appreciated!

The following is the form code:

// Written by: Carter Williams

// Description: Memory leak with datagridview datasources.

using System;

using System.Data;

using System.Windows.Forms;

namespace WindowsApplication1

{

public partial class Form1 : Form

{

DataTable myTable = new DataTable();

public Form1()

{

InitializeComponent();

// Add the column so we don't have to add it every time

// Note that the leak happens even if we do add it all the time.

myTable.Columns.Add("test");

// Set the datasource to our datatable. If we set the datasource every click,

// Then WAY more memory gets leaked... so I'll start here with the small stuff.

dataGridView1.DataSource = myTable;

}

private void button1_Click(object sender, EventArgs e)

{

// This clears the rows but doesn't clear the columns

myTable.Clear();

// Add the rows back in

myTable.Rows.Add("this");

myTable.Rows.Add("is");

myTable.Rows.Add("a");

myTable.Rows.Add("test");

// Collect the garbage

GC.Collect();

// I know I don't need this because the next line should wait but whatever...

// Wait for the garbage collection to finish

GC.WaitForPendingFinalizers();

// Wait for the garbage collection to finish and show the memory used

textBox1.Text = GC.GetTotalMemory(true).ToString();

}

}

}

Simoyd at 2007-9-4 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 3

Hi,

Your thread seems to be more appropriate here, since it's about issues regarding the very core of .NET: Security, performance, hosting, base classes, interop, reliability, debugging, GC, and profiling and hope you find satisfactory answers.

Thank you for understanding

FigoFei-MSFT at 2007-9-4 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 4

Was there supposed to be a link to a more appropriate forum? I expected the word "here" to be a hyperlink?

Im having the same sort of problems with a memory leak and searching for answers found this thread...

BradR at 2007-9-4 > top of Msdn Tech,.NET Development,Common Language Runtime...

.NET Development

Site Classified