Надежна ли сериализация для оценки размера объекта?

Я использую сериализацию, чтобы оценить объем памяти, используемый для объекта. Я уже прочитал это и this. Итак, я знаю, что может быть лучше использовать профилировщик или sizeof (для типов значений).

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

Меня особенно интересуют механизмы сериализации C #.


person Community    schedule 17.04.2009    source источник
comment
Двоичная сериализация или XML? XML будет иметь / значительную / разницу, в то время как двоичный код может быть более или менее точным, если вы просто ищете общую оценку.   -  person Spencer Ruport    schedule 17.04.2009
comment
@Spencer - Я бы сказал, что ни то, ни другое не подходит для этой цели ...   -  person Marc Gravell    schedule 17.04.2009
comment
Почему это вики сообщества?   -  person Jakob Christensen    schedule 17.04.2009


Ответы (2)


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

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

Таким образом, вы можете получить номер в результате сериализации, но это не тот тот же номер.

Трудно получить точное представление о размере графа объекта. SOS может помочь; в противном случае создайте из них целую кучу и разделите. Грубый, но это может сработать.

person Community    schedule 17.04.2009

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

/// <summary>
/// Gets the memory cost of a reference type.
/// </summary>
/// <param name="type">The type for which to get the cost. It must have a
/// public parameterless constructor.</param>
/// <returns>The number of bytes occupied by a default-constructed
/// instance of the reference type, including any sub-objects it creates
/// during construction. Returns -1 if the type does not have a public
/// parameterless constructor.</returns>
public static int MemoryCost(Type type)
{
  // Make garbage collection very unlikely during the execution of this function
  GC.Collect();
  GC.WaitForPendingFinalizers();

  // Get the constructor and invoke it once to run JIT and any initialization code
  ConstructorInfo constr = type.GetConstructor(Type.EmptyTypes);
  if (constr == null)
    return -1;
  object inst1 = constr.Invoke(null); // 

  int size;
  unsafe
  {
    // Create marker arrays and an instance of the type
    int[] a1 = new int[1];
    int[] a2 = new int[1];
    object inst2 = constr.Invoke(null);
    int[] a3 = new int[1];

    // Compute the size by determining how much was allocated in between
    // the marker arrays.
    fixed (int* p1 = a1)
    {
      fixed (int* p2 = a2)
      {
        fixed (int* p3 = a3)
        {
          size = (int)(((long)p3 - (long)p2) - ((long)p2 - (long)p1));
        }
      }
    }
  }
  return size;
}
person Community    schedule 17.04.2009
comment
Здесь слишком много предположений. Почему бы не использовать профилировщик памяти? - person Marek; 14.09.2010