2009-04-17 9 views
2

私は、オブジェクトに使用されるメモリの量を見積もるために、シリアル化を使用します。 私は既にthisthisを読みました。 プロファイラーやsizeof(値型の場合)を使用するほうが良いかもしれないことは知っています。オブジェクトサイズの見積もりにはシリアル化が信頼できますか?

私はシリアル化されたオブジェクトとメモリ内のオブジェクトの正確な違いは何ですか?オブジェクトサイズの見積もりに対して、シリアライゼーションが信頼できるものは何ですか?

私は特にC#のシリアル化メカニズムに興味があります。

+3

バイナリシリアル化またはXML?一般的な見積りを探しているのであれば、バイナリは多かれ少なかれ正確かもしれませんが、XMLには/かなりの違いがあります。 –

+0

@Spencer - 私はどちらもこの目的のために正確ではないと主張します... –

+0

私はバイナリシリアル化を意味しました – OutOfBound

答えて

3

シリアル化されたデータ形式は、インメモリと同じではありません。配列、ハッシュバケット/インデックスなどの複数のオブジェクトがコレクション/ディクショナリに含まれますが、生データ(シリアル化されたとき)はになります。通常はとなります。シリアル化された。

同様に、BinaryFormatterのようなものは、(冗長)のメタデータを入力の多くを含める必要があります - しかし、オブジェクトにそれだけでオブジェクトハンドルで(簡潔)型のハンドルを持っている - あなたは、シリアライズでよりデータが表示されることがありますデータ。同様に、シリアライザ(手動で最適化されていない限り)は、個々のフィールドをトークン化する必要がありますが、メモリ内では、これはオブジェクトアドレスからのオフセットに暗黙的に含まれています。

の番号がシリアル化されている可能性がありますが、と同じではありません。

オブジェクトグラフのサイズを正確に知ることは難しいです。 SOSが助けるかもしれない。さもなければ、それらの全体の杼口を作り、分けなさい。粗悪ですが、うまくいくかもしれません。

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; 
} 
+0

ここではあまりにも多くの仮定があります。なぜメモリプロファイラを使用しないのですか? – Marek

関連する問題