What is the easiest way to find out how much memory an object uses in .NET?
Preferably without having to resort to a third party tool. Marshal.SizeOf or the sizeof operator look useful but only work with a restricted range of types.
Some related posts:
Asked and answered here: Determine how much memory a class uses?
The quick summary is that if you don't want to use a tool, you need to use the .NET Profiling API
The Profiling API is amazingly powerful, but I don't think it would qualify as "easy" by any stretch of the imagination, so I would strongly recommend using a memory profiling tool - there are some free ones that are OK, and some not-too-expensive commercial ones ( JetBrains dotTrace in particular) that are really good.
Because of .NET's garbage-collected nature, it's somewhat difficult to measure how much memory is really being used. If you want to measure the size of a class instance, for example, does it include the memory used by instances that your instance points to?
If the answer is no , add up the size of all of the fields: Using reflection, iterate through all members of the class; use Marshal.Sizeof(member.Type) for anything that typeof(ValueType).IsAssignableFrom(member.Type) - this measures primitive types and structs, all of which reside in the class's instance allocation. Every reference type (anything that isn't assignable to a valuetype) will take IntPtr.Size. There are a disgusting number of exceptions to this, but it might work for you.
If the answer is yes , you have a serious problem. Multiple things can reference a single instance, so if 'a' and 'b' both point to 'c', then RecursiveSizeOf(a) + RecursiveSizeOf(b)
would be larger than SimpleSizeOf(a) + SimpleSizeOf(b) + SimpleSizeOf(c)
.
Even worse, measuring recursively can lead you down circular references, or lead you to objects you don't intend to measure - if a class is referencing a mutex, for example, that mutex may point to the thread that owns it. That thread may point to all of its local variables, which point to some C# framework structures... you may end up measuring your entire program.
It might help to understand that a garbage-collected language like C# is somewhat "fuzzy" (from a completely non-technical sense) in the way it draws distinctions between objects and units of memory. This is a lot of what Marshal
mitigates - marshaling rules ensure that the struct you're marshaling (or measuring) has a well-defined memory layout, and therefore a well-defined size. In which case, you should be using well-defined, marshalable structs if you intend on using Marhsal.SizeOf().
Another option is serialization. This won't tell you specifically how much memory is in use, but it will give you a relative idea of the size of the object. But again, in order to serialize things, they have to have a well-defined layout (and therefore a well-defined size) - you accomplish by making the class appropriately serializable.
I can post implementation examples if any of the above options appeal to you.
you could also do something like this:
int startMem = GC.GetTotalMemory(true);
YourClass c = new YourClass();
int endMem = GC.GetTotalMemory(true);
int usedMeme = endMem - startMem;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.