Надежна ли сериализация для оценки размера объекта? - PullRequest
2 голосов
/ 17 апреля 2009

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

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

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

Ответы [ 2 ]

3 голосов
/ 17 апреля 2009

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

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

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

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

0 голосов
/ 17 апреля 2009

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

/// <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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...