序列化对于对象大小估计是否可靠?

时间:2009-04-17 12:33:10

标签: c# memory serialization object

我使用序列化,以估计对象使用的内存量。 我已阅读thisthis。 所以我知道使用分析器或sizeof(对于值类型)可能更好。

我想知道,序列化对象和内存中对象之间的确切区别是什么?对于对象大小估计,序列化可靠的程度是什么?

我对C#序列化机制特别感兴趣。

2 个答案:

答案 0 :(得分:3)

序列化数据形式与内存不同;例如,集合/字典将涉及项目,数组,散列桶/索引等的多个对象 - 但原始数据(序列化时)通常只是数据 - 所以你序列化时可能会看到较少的音量。

同样,像BinaryFormatter这样的东西必须包含很多(冗长的)类型元数据 - 但是在对象中它只在对象句柄中有一个(简洁的)类型句柄 - 所以你可能会看到更多序列化数据中的数据。同样,序列化程序(除非它是手动优化的)需要对各个字段进行标记 - 但在内存中这隐含在与对象地址的偏移量中。

因此,您可能会从序列化中获得 号码,但它不是相同的号码。

要准确了解对象图的大小是很棘手的。 SOS可能有所帮助;否则,创造一个整体的负荷和分裂。原油,但它可能只是工作。

答案 1 :(得分:0)

这是我用来估算托管类型的内存成本的函数。它假定对象在内存中顺序分配(而不是从大对象堆中分配),因此它不会为分配大型数组的对象提供准确的结果。它也不能绝对保证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;
}