28

私はメモリ モデルをもう少し調べて、プロセスにいくつのヒープが存在するかを理解するのに苦労しています。

では、5 つのスレッドを含む 1 つのプロセスがある場合、5 つのスタックと 1 つのヒープがあるというのは正しいでしょうか?

もしそうなら、スレッドはお互いのスタックにアクセスできますか (または、これがまさに、破損を防ぐために別のスタックを持っている理由です)、ヒープが 1 つしかない場合、明らかにすべてのスレッドがこのヒープにアクセスするため、複数のスレッドでロックする必要がありますか? 私はこれを正しく理解していますか?

4

4 に答える 4

40

はい、各スレッドには独自のスタックがあります。これは非常に必要なことです。スタックは、メソッドが終了した後、メソッドがどこに戻るかを追跡し、戻りアドレスを格納します。各スレッドは独自のコードを実行するため、独自のスタックが必要です。ローカル変数とメソッド引数もそこに格納されるため、(通常は)スレッドセーフになります。

ヒープの数は、より複雑な詳細です。ガベージコレクションされたヒープに対して1を数えています。これは、実装の観点からは完全に正しいわけではありません。3世代のヒープとラージオブジェクトヒープは論理的に異なるヒープであり、合計で4つになります。割り当てが多すぎると、この実装の詳細が重要になります。

マネージコードで完全に無視できないもう1つのものは、静的変数を格納するヒープです。これはAppDomainに関連付けられており、静的変数はAppDomainが存続する限り存続します。.NETの文献では一般的に「ローダーヒープ」と呼ばれています。実際には3つのヒープ(高頻度、低頻度、スタブヒープ)で構成されており、jittedコードと型データもそこに格納されていますが、それは核心に迫っています。

無視リストのさらに下には、ネイティブコードで使用されるヒープがあります。それらのうちの2つは、元帥クラスからすぐに見ることができます。デフォルトのプロセスヒープがあり、Windowsはそこから割り当てます。Marshal.AllocHGlobal()も同様です。また、COMがデータを格納する別のヒープがあり、Marshal.AllocCoTaskMem()がそこから割り当てます。最後に、相互運用するネイティブコードには、ランタイムサポート用の独自のヒープがあります。この種のコードで使用されるヒープの数は、プロセスにロードされるネイティブDLLの数によってのみ制限されます。これらのヒープはすべて存在しますが、直接処理することはほとんどありません。

したがって、最小で10ヒープです。

于 2012-06-26T00:12:19.850 に答える
12

要するに、はい

プロセス内のすべてのスレッドは同じヒープを共有するため、データを交換できます。各スレッドには、このスレッドでの現在のコード実行に関連する独自のスタックがあります。

スレッドに関する非常に優れたリソースは次のとおりです: http://www.albahari.com/threading/

スレッドは、アプリケーションが実行されるオペレーティング システムのプロセスに似ています。プロセスがコンピューター上で並行して実行されるように、スレッドは単一のプロセス内で並行して実行されます。プロセスは互いに完全に分離されています。スレッドの分離度は限られています。特に、スレッドは、同じアプリケーションで実行されている他のスレッドと (ヒープ) メモリを共有します。これが、スレッド化が有用な理由の 1 つです。たとえば、あるスレッドがバックグラウンドでデータをフェッチし、別のスレッドが到着したデータを表示することができます。

于 2012-06-25T13:08:09.547 に答える