Байты зарезервированы в памяти для нового объекта - PullRequest
0 голосов
/ 12 ноября 2011

AFAIK, все типы получены из

 System.Object class.

Учитывая это, как я могу рассчитать, сколько байтов занимает следующий код:

Employee emp = new Employee("emp_name");

и

 List<string> empList = new List<string>();

Какой самый лучший и подходящий метод для вычисления байтов, которые они берут?

Ответы [ 2 ]

2 голосов
/ 12 ноября 2011

Вы можете использовать оператор C # sizeof, но он довольно ограничен, потому что вы должны указывать тип во время компиляции, и он может использоваться только для встроенных типов.Для класса Employee вы можете сложить их вместе, чтобы определить размер класса.Однако все ссылочные типы в классе Employee (например, String) отдельно выделяются в куче, и вам придется добавить размер этих объектов, чтобы получить общий размер.

С некоторыми хитростями ILВы можете использовать следующий метод, чтобы вычислить, сколько байтов требует тип значения (struct).Для типов ссылок он всегда будет возвращать размер ссылки (4 байта на 32 бита):

public int GetSizeOf(Type type) {
  // Create a new method.
  var method = new DynamicMethod(
    "GetSizeOf",
    typeof(UInt32),
    new Type[0],
    GetType(),
    false
  );

  // Call sizeof(type) and return the result.
  ILGenerator generator = method.GetILGenerator();
  generator.Emit(OpCodes.Sizeof, type);
  generator.Emit(OpCodes.Ret);

  // Invoke the method.
  var func = (Func<UInt32>) method.CreateDelegate(typeof(Func<UInt32>));
  return checked((Int32) func());
}

Однако даже использование sizeof для вычисления байтов не совсем точно.Объекты в куче будут иметь дополнительный дескриптор типа, который похож на указатель vtable в C ++.Как именно это делается, - это деталь реализации среды выполнения .NET.

1 голос
/ 12 ноября 2011

Ну, по словам не кого иного, как Вэнса Моррисона , нет официального способа определить это. Вся надежда еще не потеряна, и у вас есть несколько вариантов (вне моей головы):

  • двоичная сериализация / десериализация (как описано Ройи Намиром)
  • отражение (рекурсивно складывать все размеры полей, пока граф объекта не будет полностью обнаружен); или
  • перебор (создайте большой массив ваших объектов, измерьте выделенную память до / после выделения, используя статический метод GC.GetTotalMemory (), и разделите на размер массива)

Все эти решения могут только приблизиться к размеру выделения, к сожалению, до тех пор, пока Microsoft официально не добавит такую ​​функцию.

...