Get byte size of List<T>

17,474

Solution 1

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

Solution 2

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.

Solution 3

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.

Share:
17,474
Shalan
Author by

Shalan

Updated on June 04, 2022

Comments

  • Shalan
    Shalan about 2 years

    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.

  • Shalan
    Shalan over 14 years
    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
    Shalan over 14 years
    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
    Shalan over 14 years
    "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
    Shalan over 14 years
    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
  • Jon Skeet
    Jon Skeet over 14 years
    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.
  • Shalan
    Shalan over 14 years
    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!
  • Yasser Jarouf
    Yasser Jarouf about 4 years
    Must not forget using [Serializable] for strongly typed objects