Подтвердить что ты не робот

Способы определения размера сложного объекта в .NET?

Существуют ли способы определения общего размера сложного объекта в .NET? Этот объект состоит из других объектов и может содержать ссылки на другие сложные объекты. Некоторые объекты, инкапсулированные этим объектом, могут быть POD, другие - нет.

4b9b3361

Ответ 1

То, что у вас есть, не является "сложным объектом", это графом объектов. Чтобы определить его общий размер, вам нужно пройти этот график - начиная с некоторого корневого объекта и используя Reflection, чтобы перечислять поля ссылочных типов и извлекать их значения (и, конечно, проверять циклы).

Чтобы получить размер конкретного объекта на графике, см. этот ответ на соответствующий вопрос, но обратите внимание, что это злой хак, полностью неподдерживаемый, может (и может быть уже сломан), и может привести к оплодотворению геноцида котенка в небесных сферах. Тем не менее, нет "не-хакерского" способа получения точного значения, поскольку по определению это детали реализации - вы не должны им пользоваться. И для того, чтобы узнать об использовании памяти в приложении во время отладки/профилирования, взлом достаточно хорош.

Ответ 2

Проще говоря, нет способа узнать. Предполагая, что все объекты сериализуемы, вы можете использовать BinaryFormatter для их сериализации в двоичный блок, а затем прочитать размер этого. Однако это будет включать некоторые метаданные и раздуть фактический размер объекта (но это будет разумная оценка).

Для типов значений вы должны использовать Marshal.SizeOf(), только он не принимает во внимание любые подобъекты. Он будет вычислять любой внутренний ссылочный тип как размер указателя на него.

Отражение - это другой способ, но не будет раскрывать какие-либо частные члены, занимающие память. Итак, если я не ошибаюсь, нет способа сделать это правильно.

Ответ 3

Tricky...

Что делать, если два объекта указывают на одну и ту же строковую переменную. Кто "владеет" строкой? Мне кажется, вам нужно смоделировать сборку мусора, чтобы получить верный ответ. Не совсем легкий вес.

Ответ 4

Дайте System.Runtime.InteropServices.Marshal.SizeOf() снимок.

Ответ 5

Ранее упоминался в другом месте в StackOverflow:

Найти размер экземпляра объекта в байтах в С#

Вам нужно ввести небезопасный код (из-за операций указателя, необходимых для этого) - код выглядит следующим образом:

static unsafe int CalcSize(object obj)
{
    RuntimeTypeHandle th = obj.GetType().TypeHandle;
    int size = *(*(int**)&th + 1);
    return size;
}

Также не забудьте отметить настройки проекта (Project- > Build tab) на "Разрешить небезопасный код".