dataset in datagrid

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.
Post Reply
stijn
Posts: 23
Joined: Thu Jun 28, 2007 2:57 pm

dataset in datagrid

Post by stijn » Wed Apr 30, 2008 9:55 pm

Hi,

i wrote a test program to help me understand datagrid en dataset behaviour :
I defined a dataset with 10 string , 5 decimal and 5 datetime columns,
I added a datagrid and 2 buttons to 1 form,
the first button will instantiate a new set, and fill it with 10000 rows,
and then add the dataset to the grid,

the second button will clear the grid, and the set , or at least try to clear it
after pressing both buttons , the following remains in memory :

Namespace Name Live instances New live instances Removed live instances Delta live instances Live bytes Max live instance size Min live instance size Delta live bytes Allocs/sec Bytes/sec
Unchecked System Decimal[] 5 5 0 5 1310780 262156 262156 1310780 3,66 238766,5
Unchecked System String[] 22 22 0 22 656220 65552 36 656220 11,52 119650,9
Unchecked System DateTime[] 5 5 0 5 655420 131084 131084 655420 3,66 119405,2

rootpath for the decimal[]
System.Data.Common DecimalStorage
System.Data DataColumn
WindowsFormsApplication2 DataSet1.ttTableDataTable
WindowsFormsApplication2 DataSet1
WindowsFormsApplication2 Form1
System.Windows.Forms Application.ThreadContext
System.Windows.Forms Application.ComponentManager System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int, int, int)

the program :
namespace WindowsFormsApplication2 {
public partial class Form1 : Form {

DataSet1 ds = null;
public Form1 ()
{
InitializeComponent();
}
private void toolStripButton1_Click (object sender, EventArgs e)
{
ds = new DataSet1();
for (int i = 0; i < 10000; i++) {
ds.ttTable.AddttTableRow(System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
System.DateTime.Now.ToLongDateString(),
(decimal)System.DateTime.Now.Ticks,
(decimal)System.DateTime.Now.Ticks,
(decimal)System.DateTime.Now.Ticks,
(decimal)System.DateTime.Now.Ticks,
(decimal)System.DateTime.Now.Ticks,
System.DateTime.Now,
System.DateTime.Now,
System.DateTime.Now,
System.DateTime.Now,
System.DateTime.Now);
}
dataGridView1.AutoGenerateColumns = true;
this.dataGridView1.DataSource = ds;
this.dataGridView1.DataMember = "ttTable";
}

private void toolStripButton2_Click (object sender, EventArgs e)
{

if (ds != null) {
//ds.ttTable.Columns.Clear();
ds.ttTable.Clear();

ds.Clear();
ds.Dispose();
}

if (this.dataGridView1.DataSource != null) {

(dataGridView1.DataSource as DataSet1).Clear();
(dataGridView1.DataSource as DataSet1).Dispose();
this.dataGridView1.Columns.Clear();
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();

return;

}

}
}

the only way i seem to be able to fix this, is by calling
ds.ttTable.Columns.Clear(); as well,
which wouldnt be a problem in this case, but would probably cause me problem when i define the columns my self instead of relying on
dataGridView1.AutoGenerateColumns = true;

because then i would have to execute all the column code generated by VS2008 each time again ...

Am I missing something ? or is clearing each column collection on each table really necessary ?

Andreas Suurkuusk
Posts: 1029
Joined: Wed Mar 02, 2005 7:53 pm

Post by Andreas Suurkuusk » Fri May 02, 2008 7:16 am

The new Decimal[], DateTime[], and string[] instances you see are used by the DataTable as storage for a single row record. All rows are removed when you clear the table, but since the columns still exist, the column specific data is still kept alive. If you repeat the add/clear action, you will notice that the number of string[], Decimal[], DateTime[], and Decimal instances has not increased. Even though you have "New" and "Removed" instances, the "Delta" value is zero. So in this case I don't believe there's a memory leak. And, as you mentioned, the column data is removed when you clear the columns.

However, I noticed that a few new instances of WeakReference, string, and BindingContext.HashKey were created when assigning the new DataSource. The DataSource is stored in a Hashtable in BindingContext and when the DataSource is reassigned, a new hashkey is generated. The old DataSource key is never removed from the Hashtable, even though the Target is now null. I think that this is a minor problem; only the HashKey (and the related WeakReference and string) is "leaked", and everything will be GCed when the DataGridView is disposed (e.g. when closing the Form).
Best regards,

Andreas Suurkuusk
SciTech Software AB

Post Reply

Who is online

Users browsing this forum: No registered users and 25 guests