Как получить размер объекта в памяти?

Мне нужно знать, сколько байтов мой объект потребляет в памяти (в С#). например, мой Hashtable, или SortedList, или List<String>.

Ответ 1

это может быть не совсем точно, но это достаточно близко для меня

long size = 0;
object o = new object();
using (Stream s = new MemoryStream()) {
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(s, o);
    size = s.Length;
}

Ответ 2

Я не думаю, что вы можете получить его напрямую, но есть несколько способов найти его косвенно.

Одним из способов является использование метода GC.GetTotalMemory для измерения объема памяти, использованного до и после создания объекта. Это не будет идеально, но пока вы контролируете остальную часть приложения, вы можете получать интересующую вас информацию.

Кроме того, вы можете использовать профилировщик для получения информации или использовать профилирование API для получения информации в коде. Но я думаю, что это будет нелегко использовать.

Смотрите , чтобы узнать, сколько памяти используется объектом в С#? для аналогичного вопроса.

Ответ 3

Неуправляемый объект:

  • Marshal.SizeOf(object yourObj);

Типы значений:

  • sizeof(object val)

Управляемый объект:

Ответ 4

ОК, на этот вопрос был дан ответ, и ответ принят, но кто-то попросил меня ответить на мой вопрос, чтобы вы пошли.

Прежде всего, нельзя сказать точно. Это внутренняя деталь реализации и не документирована. Однако на основе объектов, включенных в другой объект. Теперь, как мы вычисляем потребность в памяти для наших кешированных объектов?

Я ранее затронул эту тему в этой статье :

Теперь, как мы вычисляем потребность в памяти для нашего кэширования объекты? Ну, как большинство из вас знает, Int32 и float - четыре байты, double и DateTime 8 байтов, char на самом деле два байта (не один байт) и т.д. Строка немного сложнее, 2 * (n + 1), где n это длина строки. Для объектов это будет зависеть от их члены: просто суммируйте требования к памяти всех ее членов, запоминание всех ссылок на объекты - это просто 4 байтовых указателя на 32 бит. Теперь это на самом деле не совсем так, мы не позаботились накладных расходов каждого объекта в куче. Я не уверен, что вам нужно чтобы быть обеспокоенным этим, но я полагаю, если вы будете использовать лоты небольших объектов, вам придется взять накладные расходы в рассмотрение. Каждый кучный объект стоит столько же, сколько его примитивные типы, плюс четыре байта для ссылок на объекты (на 32-битной машине, хотя BizTalk также запускает 32-битное на 64-битных машинах), плюс 4 байта для type object pointer, и я думаю, 4 байта для индекса блока синхронизации. Зачем это дополнительные накладные расходы важны? Ну, представьте себе, что у нас есть класс с двумя членами Int32; в этом случае требование к памяти 16 байтов, а не 8.

Ответ 5

Следующий фрагмент кода должен возвращать размер в байтах любого переданного ему объекта, если он может быть сериализован. Я получил это от коллеги в Quixant, чтобы решить проблему написания SRAM на игровой платформе. Надеюсь, что это поможет. Кредит и благодарность Карло Виттучи.

/// <summary>
/// Calculates the lenght in bytes of an object 
/// and returns the size 
/// </summary>
/// <param name="TestObject"></param>
/// <returns></returns>
private int GetObjectSize(object TestObject)
{
    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    byte[] Array;
    bf.Serialize(ms, TestObject);
    Array = ms.ToArray();
    return Array.Length;
}

Ответ 6

В режиме отладки

загрузить SOS

и выполните команду dumpheap.

Ответ 7

Вы можете попробовать метод Marshal.SizeOf и sizeof.

Не уверен, что они будут работать на HashTables и т.д., но отпустите его... это может сработать.