views:

1582

answers:

3

I've got a generic Dictionary that holds a bunch of data. I'd like to start removing items (I know how to determine which ones) when the size of the Dictionary starts taking up too much memory.

What's the best way for my program to monitor the RAM used by this Dictionary?

Each item in the Dictionary is a variable size.

+1  A: 

Work out the size of each item and multiply by the Dictionary.Count

One way is shown here:

An approximate way to determine the size of object usage in memory can be done by checking the total memory before and after the creation of the object. In the following example it is assumed you have a class named foo.

long StopBytes = 0;
foo myFoo;

long StartBytes = System.GC.GetTotalMemory(true);
myFoo = new foo();
StopBytes = System.GC.GetTotalMemory(true);
GC.KeepAlive(myFoo); // This ensure a reference to object keeps object in memory

MessageBox.Show("Size is " + ((long)(StopBytes - StartBytes)).ToString());

C# has a 'sizeof' operator that works like it does in C/C++, however it returns the size that a field of that type will be. Thus for reference types (class, not struct), it will always return the size of a pointer (4 on 32 bit systems). Use System.Runtime.InteropServices.Marshal.SizeOf() instead.

Mitch Wheat
"Work out the size of each item." How?
BFree
as mentioned above this isn't thread safe and could actually return a negative number.
jellomonkey
@jellomonkey: true but not likely. I wouldn't suggest he do this in the actual production code; rather in a test project to determine size (assuming they won't change often).
Mitch Wheat
A: 

When you adding something to Dictionary, calculate size of item adding and keep sum of every added item as single int value, when you're removing item from dictionary decrement this value.

dimarzionist
A: 

I don't believe there is any API which will give you the true size of an object, but it can be determined by measuring the ammount of memory used before and after the object is created; however, that is not really thread safe.

You could use System.Runtime.InteropServices.Marshal.SizeOf() even though this will not give you an accurate size it will give you an accurate comparison point so that you can say something like: if the size of the object increases by X% then remove Y number of elements.

Also, you could try to keep a running total but if items in the collection are editable you will need to make sure that every addition, removal, and edit is included in the calculation. You are still left with the problem of properly measuring the items being added and removed and as stated above I don't believe there is an API that will do this accurately.

jellomonkey