2012-07-26 22 views
5

私は、自分の言語としてC#で.NET Frameworkを始めたばかりです。私はJavaでGCの概念を幾分理解しており、今日も.NETで同じ概念を再考しています。ガベージコレクションはスタックに影響しますか?

C#では、値の型がスタックに置かれます(Javaには、ローカル変数がスタックに置かれます)。しかし、C#では、さらに値の型にstructが含まれています。したがって、structもスタックに配置されます。最悪の場合、多くのメソッド呼び出しがあり、スタックに多数のメソッドが頻繁に設定され、各メソッドには多くのローカル値型があり、多くのローカル値型を持つstructが多数あります。スタック?私が研究したこと(そして私が学んだことの一部)から、私はそれがそうしないことを理解する。主にスタックの内容を操作するにはオーバーヘッドが多くなります。また、GCは参照を参照するだけでスタックを調べるだけです。

同じトピックに関するもう1つの質問を追加するだけです.GCへの呼び出しを強制する(JavaではSystem.gc()と同じですが、C#と同等ではありません)ので、GCルーチンが確実に呼び出されるわけではありません。だから私はそのような呼び出しをどこに置くべきですか?私はGCを実行する必要があると思います。それとも、ランタイム環境に残しておけばいいのですか?

注:ここから概念をリンクしようとしているため、Javaタグを追加しました。私は、2つの別々のランタイム環境におけるGCの内部機能は間違いなく異なると理解していますが、基本的な考え方は同じであると思います。

答えて

2

いいえガベージコレクションは、Javaスタック上のオブジェクトには影響しません。

GCは、jvmのヒープ内のオブジェクトにのみ影響します。 Java GCプロセスは多層化されているため、非常に複雑で、読み解く価値があります。それがどのように動作するかをよく把握するには、http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.htmlのようなサイトをチェックしてください。

システムのGC を強制する限り、それは悪い考えであるです。 jvmは、GCを実行する必要があるときに、より良いアイデアを持っています。大きなオブジェクトを割り当てようとしている場合、jvmはスペースを確保してGCを実行する必要がないようにします。

EDIT 私の悪いことに、あなたはC#についてJavaよりも心配です。同じメモリ管理のプリンシパルが適用され、スタックは影響を受けず、明示的にGCなどを実行しません。C#はjavaと同様の管理機能を持つように設計されています。 http://msdn.microsoft.com/en-us/library/ms973837.aspx

+0

お返事ありがとうございます。私はそれについてもっと読んだ後に私は戻ってきます。 –

1

AFAIK GCはスタックに影響しません。 HEAPメモリにのみ影響します。スタックフレームはメソッド呼び出し時に作成され、メソッド終了時に削除されます。

EDIT

このMSDN articleは、GCは、.NETフレームワークの中でどのように機能するかを説明します。

+0

これはJava、C#、またはその両方で動作しますか? –

+0

これはJavaの場合のみです。私はC#についてはあまりよく分かりませんが、私の推測はC#が同様のプリミティブに従っていることです。 – kosa

+0

私の質問はC#の文脈にありますが、あなたの応答に感謝します。 –

1

あなたは.NETのためにこれを読めば、それだけでに取り組んでいますがヒープを管理:

http://msdn.microsoft.com/en-us/library/ee787088.aspx

MSDNは、ここでのGCの親トピックがあり、情報の宝庫であると思われますCLR:

http://msdn.microsoft.com/en-us/library/0xy59wtx

+0

リンクありがとうございました。私は疑問がある場合に備えて、読んで返信します。 –

+0

@KazekageGaara問題ありません! –

2

スタックは、ガベージコレクタの援助を必要としません。なぜなら、スタックフレーム(スタック内の現在の実行の範囲)から移動すると、新しいスタックフレームを作成するときに、コンテンツを含むフレーム全体が解放され(上書きされるためです。

function foo(int a, int b) { 
    int i; 
    doStuff(); 
} 

関数を入力するときはフレームの終了時に、フレームが割り当てられるように割り当てられた変数が割り当てられているスタック全体フレームが割り当て解除、破棄されるスタックフレーム(粗い視覚化)

---- Frame Start ---- 
(value for parameter a) 
(value for parameter b) 
(other items needed for tracking execution) 
(extra stack frame space 
    (value for stack allocated i) 
) 
---- End of Frame ---- 

を作成しますフレーム割り当て変数のメモリ。

通常、Javaはオブジェクト全体ではなく、オブジェクト参照とスタックローカルプリミティブをスタックに割り当てます。最近の最適化では、フレーム外に到達できないオブジェクトのスタック内割り当てが可能になります。それはあなたが頼りにできるものとはみなされないという条件を持っています。

つまり、スタックフレーム内の参照は通常、正常にガベージコレクションされるヒープを指しています。

+0

私はスタックの概念を理解しています。しかし、私はスタックが多くの関数呼び出し(他のフレームをスタックからポップされていない他の関数などを呼び出す関数など)でいっぱいになる最悪のシナリオで尋ねました。しかし、スタックが決して影響を受けることはありません。 –

+1

スタック領域に割り当てられたメモリをオーバーランするのに十分なスタックフレームが必要な場合、フレームはヒープに移動されません。代わりに、stackoverflowエラーが発生し、処理が停止します。 –

+0

私はあなたの答えをさらにアップアップし、それを受け入れることができればと思っています。私はスタックのシナリオをよく理解してくれて、またstackoverflowerrorというものの存在を思い出させてくれたので、しかし、もう一つの答えは全体的な解決策を提供しました。とにかくおかげで。 –

1

.NETガベージコレクションについては、MSDNのGarbage Collectionで詳しく説明しています。ガベージコレクタは、マネージヒープ内のメモリのみを追跡します。

関連する問題