Какой самый простой способ узнать, сколько памяти использует объект в .NET? - PullRequest
2 голосов
/ 01 октября 2008

Какой самый простой способ узнать, сколько памяти использует объект в .NET?

Желательно, не прибегая к сторонним инструментам. Marshal.SizeOf или оператор sizeof выглядят полезными, но работают только с ограниченным диапазоном типов.

Некоторые похожие посты:

Ответы [ 3 ]

2 голосов
/ 01 октября 2008

На вопрос и ответ здесь: Определите, сколько памяти использует класс?

Вкратце: если вы не хотите использовать инструмент, вам нужно использовать .NET Profiling API

API профилирования является поразительно мощным, но я не думаю, что его можно было бы назвать «легким» при любых обстоятельствах, поэтому я настоятельно рекомендую использовать инструмент профилирования памяти - есть несколько бесплатных, которые в порядке, и некоторые не слишком дорогие коммерческие (в частности, JetBrains dotTrace ), которые действительно хороши.

0 голосов
/ 31 января 2013

Из-за того, что .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 ().

Другой вариант - сериализация. Это не скажет вам конкретно, сколько памяти используется, но даст вам относительное представление о размере объекта. Но опять же, чтобы сериализовать вещи, они должны иметь четко определенную компоновку (и, следовательно, четко определенный размер) - вы делаете это, делая класс соответствующим образом сериализуемым.

Я могу опубликовать примеры реализации, если вам понравятся какие-либо из перечисленных выше вариантов.

0 голосов
/ 01 октября 2008

Вы также можете сделать что-то вроде этого:

int startMem = GC.GetTotalMemory(true);
YourClass c = new YourClass();
int endMem = GC.GetTotalMemory(true);
int usedMeme = endMem - startMem;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...