2009-08-13 8 views
9

「オブジェクト」から継承し、フィールド/プロパティを持たないオブジェクトのメモリ量はどれくらいですか?そして私は方法がそうしないと思います。右 ?私は.netオブジェクトのために話しています。C#オブジェクトから取ったメモリ

+0

良い質問。私はそれらの数百万を作成し、前と後のメモリの違いを参照して言うだろう。誰かがすでにこれをしていない限り。 –

+0

それは私が尋ねた理由です。私は数百万のオブジェクトでアプリケーションのメモリ使用量を知る必要がありました。だから32ビットのアプリの答えは、すべてのフィールドのサイズ+8バイトです。 –

答えて

11

さて、アンドリューとGuffaの両方が、私が間違っていると信じている答えを...与えているよう

(x86版)のすべてのオブジェクトのための8バイトのオーバーヘッドがありますが、そこだ 12の最小サイズバイト。私はなぜ知らない...しかし、それは、これら2つのクラスが両方は、インスタンスごとに12バイトを取ることを意味します

public class OneField 
{ 
    private int field; 
} 

public class NoFields 
{ 
} 

テスト:私は意図的ではないたので

using System; 

public class OneField 
{ 
    private int field; 
} 

public class NoFields {} 

public class Test 
{ 
    static void Main(string[] args) 
    { 
     int size = int.Parse(args[0]); 
     switch (args[1]) 
     { 
      case "NoFields": 
       TestNoFields(size); 
       break; 
      case "OneField": 
       TestOneField(size); 
       break; 
     } 
    } 

    static void TestNoFields(int size) 
    { 
     NoFields[] array = new NoFields[size]; 
     long start = GC.GetTotalMemory(true); 
     for (int i=0; i < size; i++) 
     { 
      array[i] = new NoFields(); 
     } 
     long end = GC.GetTotalMemory(true); 
     GC.KeepAlive(array); 
     Console.WriteLine("Size per instance: {0}", 
          (end-start)/(double)size); 
    } 

    static void TestOneField(int size) 
    { 
     OneField[] array = new OneField[size]; 
     long start = GC.GetTotalMemory(true); 
     for (int i=0; i < size; i++) 
     { 
      array[i] = new OneField(); 
     } 
     long end = GC.GetTotalMemory(true); 
     GC.KeepAlive(array); 
     Console.WriteLine("Size per instance: {0}", 
          (end-start)/(double)size); 
    } 
} 

これは醜いですジェネリックタイプや問題の原因となる可能性のあるものは削除されます。いくつかのテストが実行されます。

>test 1000000 NoFields 
Size per instance: 12.000024 
>test 1000000 OneField 
Size per instance: 12.000024 
>test 1000 NoFields 
Size per instance: 12 
>test 1000 OneField 
Size per instance: 12 

(番号は常に正確な整数ではない理由JITtingオーバーヘッドなどを説明して - 私は浮動小数点で除算を行うので、その理由。)

テストを余分にint型のフィールドショーで使用量が16まで増え、実際に何か分かりやすいことが証明されています:)

+0

最小限の12バイトについては良い点がありますが、質問の精神は、System.Objectからどのような情報が "継承されたか"正確に関係していると思います。あなたは正しいですが、x86では、最初のフィールドは「フリー」なので、「System.Object」のオーバーヘッドがなくても、最初の3つのフィールドは空いていた可能性があります:)さらに、この重要な区別のために+1してください。 –

0

リファレンスタイプで発生する唯一のオーバーヘッドは、タイプオブジェクトポインタの場合は4バイト、シンクブロックインデックスの場合は4バイトです。

合計で8バイトのオーバーヘッド。

3

オブジェクトには、それ自身のデータに加えて2つの参照/ポインタがあります。

したがって、32ビットシステムではオブジェクトは8バイト、64ビットシステムでは16バイトとなります。

訂正:
Jonが述べたように、オブジェクトの最小サイズは12バイトです。これまでに私が見つけた情報は、GCがこれを必要としていると言います。

+4

いいえ - 何らかの理由でx86に最小オブジェクトサイズが12バイトありますが、最初のフィールドは「空き」です:) –

+0

これに基づいてhttp://msdn.microsoft.com/en-us/magazine/cc163791 .aspx GCはオブジェクトが何らかの理由で少なくとも12バイト必要です。 – Guffa

関連する問題