Infosys Microsoft Alliance and Solutions blog

« Early feedback from our customers | Main | Silverlight 4 and Windows Phone 7 »

Size of a .net object

While trying to debug a service call, where we suspected a buffer overrun situation, we wanted to find out the size of the object being returned by the service call. However finding size of a .net object is not trivial and if you thought you could do a sizeof(object), then you are wrong. This will only return the size of the object based on the size of each field in object that itself is based on the type of the field. This doesn't returns the size of the object in memory with data loaded into it.

Another option people try to use is Marshal.Sizeof(object), but this gives the size of the unmanaged representation of the object and the layout in managed and unmanaged world may be very different.

Chris Brumme (earlier was in the CLR team) had written that there is no direct API in .net to provide this size and he has explained it here.

Some forums talk about using a serialization approach. So you essentially create a memory stream and then use  binary formatter and serialize the object in the stream and then get the size of the stream. While this can be used, be aware of potential pitfall. The size thus obtained is really the serialized size and not the in-memory size. Why will the two differ? These can differ for

  1. The layout of the object in memory/byte alignment etc will cause the diference and
  2. If the object overrides and has custom serialiation, it might alter what all get's serialized and thus the size will differ.

Another option, that possibly is the best according to me is to use GC.GetTotalMemory() API before and after the call to create the object. See details here. However this itself has its own challenges in that this isn't thread safe, as the blog also points out. Multiple things can happen between the two calls to GC and other threads may release or allocate other objects and hence the size difference you will get may not truely reflect the size of only this object. Another aspect is that this object itself may need multiple steps to fully populate and hence enclosing these steps within calls to GC.GetTotalMemory() may be tricky.

There is one last option, which will mostly be 100% accurate, and that is to take a memory dump of the process once the object is allocated and then using WinDBG find out the total size of the object by using the objsize command. See some explaination of how to use WinDBG for this purpose here.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Please key in the two words you see in the box to validate your identity as an authentic user and reduce spam.

Subscribe to this blog's feed

Follow us on

Blogger Profiles

Infosys on Twitter