2009-08-24 15 views
7

多くの人が混乱しています。CLRは静的クラスをどこに格納しますか?

通常のクラスは、そのデータをヒープに格納しますか?スタックへの参照(Pointer)。

スタックがスコープから外れると、次回はガベージコレクタが起動し、メモリをヒープから削除します。

静的クラスの場合、メモリ全体がプログラム全体に存在する必要があるため、ガベージコレクタによってメモリをクリーンにすることはできません。そして最初にリファレンスを得る方法はありません。

コンソールと呼ぶとき。たとえば、書き込み?プログラムはどこから参考文献を取得しますか(静的クラスへの参照はどこに保存されますか)それとも、それを直接呼び出すのですか?

+4

私はこの質問の一部を理解していません。 「その価値」と「その基準」とはどういう意味ですか? –

+0

私は彼が実行可能コードとデータメンバーをどのように分離するかについて話していると思います。 –

+1

他の問題の中でも、それは "それ"です。 – jason

答えて

16

私はあなたがメモリはメモリがに開催される方法と住んと混乱のクラスだと思います。通常のクラスのインスタンスを作成すると、そのインスタンスのメモリはヒープ上に存在します。 A リファレンスは、ヒープ上のオブジェクト内にある可能性があります(オブジェクトの別のインスタンス内にメンバ変数を設定した場合)。 (メソッド内のオブジェクトへの変数を宣言したり、関数呼び出しに渡した場合など)、またはグローバルルートのリストに含まれている可能性があります(スタティックリファレンスの場合、たとえばSingleton参照)。

静的クラスはインスタンス化できません。どこにでもクラスへの "参照"はありません(型情報を除く)。そのメソッドは、CLRがアセンブリをロードするときにメモリにロードされる関数です。これらのメソッドの1つを指すデリゲートを作成することはできますが、それはクラスのインスタンスへの参照を作成しません。これは単なる関数へのポインタです。

たとえば、このコードを見て:

class ObjectWrapper 
{ 
    Object obj = new Object(); 
} 

static void Main(string[] args) 
{ 
    ObjectWrapper wrapper = new ObjectWrapper(); 
    ... 
} 

メインメソッドがObjectWrapperクラスのインスタンスを作成します。このインスタンスはヒープ上に存在します。

ObjectWrapperインスタンスの内部には、ヒープ上に存在するObjectクラスのインスタンスがあります。このクラスへの参照はインスタンスの内部にあるので、参照を「ヒープでの生活」と考えることができます。

さて、次のコードにこれを比較します

class Singleton 
{ 
    static readonly instance = new Singleton(); 
} 

シングルトンオブジェクトのインスタンスは、あまりにも、ヒープ上に住んでいます。しかし、の参照は静的な参照です。これはCLRによってグローバルまたは "ルート"参照のリストで管理されます。

は今、この静的クラスを見て:

class ObjectWrapper 
{ 
    Object obj = new Object(); 
} 

static class HelperMethods 
{ 
    static int DoSomethingUseful(ObjectWrapper wrapper1) 
    { 
     ObjectWraper wrapper2 = wrapper1; 
     // code here 
    } 
} 

HelperMethodsを静的なクラスです。 HelperMethodsクラスをインスタンス化することはできません。このクラスのオブジェクトはヒープには存在できません。ただし、DoSomethingUsefulメソッドでは、スタック上のObjectWrapperクラスのインスタンスへの参照が2つあります。 1つは渡され、1つはメソッドの中で宣言されます。

+0

+1、詳細を楽しんだ。 – user7116

+0

「ルーツ」については、この記事で.NETのGCアルゴリズムについて説明し、ルーツがGCでどのように役割を果たすかを明確にしています。 http://msdn.microsoft.com/en-us/magazine/bb985010.aspx – felideon

+0

この回答には、完全に正確ではない点がいくつかあります。 1つは、「どこにもありません」というステートメントは「どこにでも」というステートメントは間違っています。静的またはそれ以外のすべての型への参照は、ローダーヒープ上に保持されます。タイプ・システム全体は、タイプとそのメンバーへの参照とともに、ローダー・ヒープ上で管理されます。また、 'このクラスはヒープ上のメモリを消費しません'は間違っています... GCヒープスペースを消費しない間に、ヒープスペースをローダーヒープで消費します。単純にポインタである参照のアイデアも間違っています... CLRは多くのレベルの間接参照を使用します。 – jrista

6

簡単な答えを得るために、静的クラスはローダーヒープと呼ばれるものに「格納」されます。ローダーヒープは、非常に予測可能で厳しい成長率を持つ特別な非GCヒールです。 .NETアプリケーションが起動すると、実際にいくつかのAppDomainsが作成されます。プライマリアプリケーションドメインに加えて、システムネームスペースとmscorelib、特別なヒープ(ローダーヒープなど)、およびCLR自体を含むシステムドメインと共有アプリケーションドメインがあります。完全に詳細な説明については

は、以下のMSDNマガジンの記事読んで:数年前からあるにもかかわらず

Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects

を、それはまだ適用されます。 (ただし、.NET 4.0がこれを大きく変更したとは言えません)

関連する問題