Continious DataTable.Select without AcceptChanges on every table leaks memory

H

Helge C. Rutz

Hi everybody,

we had very strange memory usage in our application when continiously
updating a dataset. We were able to exactly localize the problem in the
datatable.Select method.
Each time we check the datatables for changes with Select, there is an
internal index build.
These indexes are later deleted when you pass the datatable to the
dataadapter.
But in our code we have a lot of tables in the dataset where we check all
for changes and only update the ones with changes.
When the changes only occur in the same tables for a long time, the other
tables get more and more indexes consuming a lot of memory.

The following piece of code demonstrate this behaviour.
It generates more than 400Meg on my machine, and it's the Select method
doing this!
Only a call of the AcceptChanges method clears the memory.
If your machine doesn't have that much memory, be careful!
We have not examined the problem on .NET SP1, perhaps it is fixed.

For me, creating a static index without reusing it anytime looks like a bug.
Are there any designguides saying that this is not the right way to
use/update datasets?
Doesn't anybody work with datasets like that?
Any comments on that?

Helge

----------------------------------------------------
class Class1
{
[STAThread]
static void Main(string[] args)
{
// build a very simple DataSet
System.Data.DataSet ds = new DataSet();
System.Data.DataTable table = ds.Tables.Add("Table");
table.Columns.Add(new System.Data.DataColumn("ID", typeof(Guid)));

// add some Data to your one table to make the effect more dramatic ;-)
for (int i = 0; i< 10000; ++i)
{
System.Data.DataRow row = table.NewRow();
row["ID"] = Guid.NewGuid();
table.Rows.Add(row);
}
table.AcceptChanges();

// dump memory before
Class1.DumpMemory();

for(int i = 0; i <10000; ++i)
{
// this simple select (doing nothing) executed 10000 times generates over
400Meg of memory!
// And you don't get rid of it with GC.Collect()!
table.Select(null,null,DataViewRowState.ModifiedCurrent);
}
// dump memory after! Suprise!
Class1.DumpMemory();

// only if you call AcceptChanges the memory is cleared!
ds.AcceptChanges();

Class1.DumpMemory();
}

static void DumpMemory()
{
System.GC.Collect();
System.Console.WriteLine("TotalMemory: " +
GC.GetTotalMemory(true).ToString());
}
}
 
V

Val Mazur \(MVP\)

Hi Helge,

Try to use DataView with the filter instead Select. It could help to resolve
an issue if you dispose DataView after job is done
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top