Глупый вопрос, но в приложении winforms, над которым я сейчас работаю, я хотел бы получить количество байтов, выделенных / используемых List<[SomeObject]> в памяти (для статистических целей). Это возможно? Я просмотрел возможные варианты, но метода myList.GetTotalBytes() явно не существует.

11
Shalan 30 Ноя 2009 в 01:22

3 ответа

Лучший ответ

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

  • используйте такой инструмент, как CLR Profiler
  • используйте Marshal.SizeOf () ( возвращает неуправляемый размер объекта)
  • сериализуйте свой объект в двоичный код для приближения
7
flesh 30 Ноя 2009 в 01:25
Воах, это было быстро! спасибо 4 ответ! К сожалению, я ищу метод, доступный во время выполнения, и, надеюсь, не что-то, что потребовало бы от меня разрыва списка и повторения по каждому объекту.
 – 
Shalan
30 Ноя 2009 в 01:27
Пропустил упоминание о CLR Profiler. Никогда не использовал его раньше, но спасибо за это - я собираюсь прочитать немного больше о его использовании!
 – 
Shalan
2 Дек 2009 в 04:27

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

Биты списка:

  • Резервный массив (T[] - ссылка на массив, к которому будет иметь доступ только список)
  • Размер (int)
  • Корень синхронизации (ссылка)
  • Номер версии (int)

Сложность состоит в том, чтобы решить, сколько считать. Каждый из них довольно легко вычислить (особенно если вы знаете, что T является ссылочным типом, например), но хотите ли вы подсчитать объекты, на которые ссылаются в списке? Эти ссылки единственные или нет?

Вы говорите, что хотите знать «для статистических целей» - не могли бы вы быть более точными? Если вы можете сказать, что вас действительно интересует (и немного больше информации о том, что находится в списке и могут ли быть другие ссылки на те же объекты), мы, вероятно, могли бы помочь больше.

12
Jon Skeet 30 Ноя 2009 в 01:27
Привет, Джон, и спасибо за ответ. извините 4, не очень ясно. Список - это набор сущностей таблицы, заполняемых из запроса LINQ. И этот содержит в основном типы string и dateTime.
 – 
Shalan
30 Ноя 2009 в 01:38
"для статистических целей" - допустим, мой запрос дает коллекцию, содержащую 10 000 объектов Entity, и (если я могу вычислить это лучше) каждый объект занимает в среднем 25 байт памяти, я хотел бы получить общее количество байтов для всех объектов Entity в списке
 – 
Shalan
30 Ноя 2009 в 01:42
Как упоминалось ранее, я ищу альтернативу итерации по объектам и переходу к каждому свойству, о чем также упоминал Ян.
 – 
Shalan
30 Ноя 2009 в 01:44
1
Итак, вы действительно хотите включить все элементы списка и предполагаете, что ни на что другое не ссылается? Боюсь, что нет никакого способа получить эту информацию.
 – 
Jon Skeet
30 Ноя 2009 в 09:20

Это может быть ответ, полный коня, но я рискну и скажу, что если вы проводите статистические сравнения, выполните двоичную сериализацию объекта в MemoryStream, а затем посмотрите на его свойство Length как таковое:

    List<string> list = new List<string>
    {
        "This",
        "is",
        "a",
        "test"
    };

    using (Stream stream = new MemoryStream())
    {
        IFormatter formatter = new BinaryFormatter();

        formatter.Serialize(stream, list);
        Console.WriteLine(stream.Length);
    }

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

8
Jesse C. Slicer 30 Ноя 2009 в 08:54
1
Не забудьте использовать [Serializable] для строго типизированных объектов.
 – 
Yasser Jarouf
15 Июн 2020 в 20:14