Из-за того, что .NET собирает мусор, довольно сложно измерить, сколько памяти действительно используется. Например, если вы хотите измерить размер экземпляра класса, включает ли он память, используемую экземплярами, на которые указывает ваш экземпляр?
Если ответ не , сложите размер всех полей:
Используя рефлексию, переберите всех членов класса; используйте Marshal.Sizeof (member.Type) для всего, что typeof (ValueType) .IsAssignableFrom (member.Type) - это измеряет примитивные типы и структуры, все из которых находятся в выделении экземпляра класса. Каждый ссылочный тип (все, что не присваивается типу оценки) будет принимать IntPtr.Size. Есть отвратительное количество исключений, но это может сработать для вас.
Если ответ положительный , у вас серьезная проблема. Несколько вещей могут ссылаться на один экземпляр, поэтому если «a» и «b» оба указывают на «c», то RecursiveSizeOf(a) + RecursiveSizeOf(b)
будет больше, чем SimpleSizeOf(a) + SimpleSizeOf(b) + SimpleSizeOf(c)
.
Еще хуже, рекурсивное измерение может привести вас к циклическим ссылкам или привести к объектам, которые вы не собираетесь измерять - например, если класс ссылается на мьютекс, этот мьютекс может указывать на поток, которому он принадлежит. Этот поток может указывать на все свои локальные переменные, которые указывают на некоторые структуры фреймворка C # ... вы можете закончить измерение всей вашей программы.
Это может помочь понять, что язык сборки мусора, такой как C #, несколько «нечеткий» (в совершенно нетехническом смысле) в том, как он проводит различия между объектами и единицами памяти. Это многое из того, что Marshal
смягчает - правила маршалинга гарантируют, что структура, которую вы маршалируете (или измеряете), имеет четко определенный макет памяти и, следовательно, четко определенный размер. В этом случае вы должны использовать четко определенные маршальные структуры, если вы собираетесь использовать Marhsal.SizeOf ().
Другой вариант - сериализация. Это не скажет вам конкретно, сколько памяти используется, но даст вам относительное представление о размере объекта. Но опять же, чтобы сериализовать вещи, они должны иметь четко определенную компоновку (и, следовательно, четко определенный размер) - вы делаете это, делая класс соответствующим образом сериализуемым.
Я могу опубликовать примеры реализации, если вам понравятся какие-либо из перечисленных выше вариантов.