views:

268

answers:

4

Hi,

Silly question, but in a winforms app Im currently working on, I would like to get the amount of bytes allocated/used by a List<[SomeObject]> held in memory (for statistical purposes). Is this possible? I have searched thru the possible options, but there is obviously no myList.GetTotalBytes() method.

+2  A: 

I'm not sure the runtime provides a reliable programmatic method of getting an object's size, however there are some options open to you:

  • use a tool like CLR Profiler
  • use Marshal.SizeOf() (returns the unmanaged size of the object)
  • serialize your object to binary for an approximation
flesh
woah, that was quick! thanks 4 the reply! unfortunately, I am looking for a method available at runtime, and hopefully not something that will involve me tearing the list apart and iterating thru each object.
Shalan
missed the mention of the CLR Profiler. Never used it before, but thanks for that - im gonna go read up a bit more on using it!
Shalan
+7  A: 

It really depends on what you mean. You can predict how many bytes will be used by the list itself - but that's not the same as predicting how many bytes might be eligible for garbage collection if the list became eligible for collection.

Bits of the list:

  • The backing array (T[] - a reference to an array that only the list will have access to)
  • The size (int)
  • A sync root (reference)
  • The version number (int)

The tricky bit is deciding how much to count. Each of those is fairly easy to calculate (particularly if you know that T is a reference type, for example) but do you want to count the objects referenced by the list? Are those references the only ones, or not?

You say you want to know "for statistical purposes" - could you be more precise? If you can say what you're really interested in (and a bit more information about what's in the list and whether there may be other references to the same objects) we could probably help more.

Jon Skeet
Hi Jon, and thanx 4the reply. sorry 4 not being very clear. The List is a collection of Table Entities being populated from a LINQ query. And this one contains mainly string and dateTime types.
Shalan
"for statistical purposes" - lets say my query yields a collection containing 10,000 Entity objects, and (assuming I can calculate this better) each object occupies on avg 25 bytes of memory, I would like to get the cumulative bytes total of all Entity objects in the List
Shalan
As mentioned before, I am looking for an alternative to iterating thru the objects and drilling down to each property, as also mentioned by Jan
Shalan
So you want to actually include all the elements of the list, and you're going to assume that nothing else has a reference? There's really no way of getting that information I'm afraid.
Jon Skeet
A: 

This may be a full-of-horse-pucky answer, but I'm going to go out on a limb and say if you're doing statistical comparisons, do a binary serialize of the object to a MemoryStream and then look at its Length property as such:

    List<string> list = new List<string>
    {
        "This",
        "is",
        "a",
        "test"
    };

    using (Stream stream = new MemoryStream())
    {
        IFormatter formatter = new BinaryFormatter();

        formatter.Serialize(stream, list);
        Console.WriteLine(stream.Length);
    }

Take note that this could change between different versions of the framework and would only be useful for comparisons between object graphs within a single program.

Jesse C. Slicer
A: 

You can use YourKit .NET profiler http://www.yourkit.com/dotnet/ to get exact sizes of objects in memory. You need to capture heap memory snapshot and load it into profiler.

You'll see something like this

alt text

Profiler shows plain (shallow) object size and also retained size. It's invaluable information for memory leak hunting.

--serge

Serge