6

以下はMSDNからの抜粋です。

共通言語ランタイムは、インターン プールと呼ばれるテーブルを維持することで、文字列ストレージを節約します。このテーブルには、プログラムでプログラムによって宣言または作成された一意の各リテラル文字列への単一の参照が含まれています。したがって、特定の値を持つリテラル文字列のインスタンスは、システム内に 1 回だけ存在します。

たとえば、同じリテラル文字列を複数の変数に割り当てると、ランタイムはインターン プールからリテラル文字列への同じ参照を取得し、それを各変数に割り当てます。

Intern メソッドは、インターン プールを使用して、str の値に等しい文字列を検索します。そのような文字列が存在する場合は、インターン プール内のその参照が返されます。文字列が存在しない場合は、str への参照がインターン プールに追加され、その参照が返されます。.... アプリケーションが割り当てるメモリの総量を削減しようとしている場合は、文字列のインターンには 2 つの望ましくない副作用があることに注意してください。まず、インターンされた String オブジェクトに割り当てられたメモリは、共通言語ランタイム (CLR) が終了するまで解放されない可能性があります。

これは、CLR が実行中のすべての .net アプリに対して 1 つのインターン プールを保持するということですか? 例: プログラム A が文字列リテラル "Test" を作成し、別のプログラムが別の文字列リテラル "Test" を作成しようとした場合、同じコピーが使用されますか? 同じ質問が JVM にも当てはまります。

4

4 に答える 4

2

CLR は、インスタンスごとにインターン プールを保持します。MSDNリンクをさらに読んだ場合:

アプリケーションが割り当てるメモリの総量を削減しようとしている場合は、文字列のインターンには 2 つの望ましくない副作用があることに注意してください。まず、インターンされた String オブジェクトに割り当てられたメモリは、共通言語ランタイム (CLR) が終了するまで解放されない可能性があります。

Javaの場合、開始するJVMごとでもあります。

ただし、この記事によると:

この神話は、神話 2 とは反対の方向に進んでいます。JVM が終了するまで、内部化された文字列はメモリ内にとどまると信じている人もいます。昔はそうだったかもしれませんが、現在、内部化された文字列は、参照がなくなった場合にガベージ コレクションされます。上記のプログラムのわずかに変更されたバージョンを以下に示します。内部化された文字列への参照を時々クリアします。jconsole からプログラムの実行を追跡すると、ガベージ コレクターが参照されていない内部化された文字列によって使用されるメモリを再利用するため、PermGen スペースの使用量が増減することがわかります。

これは、Java でインターンされた文字列が実際に GC される可能性があることを意味します。

于 2011-07-04T08:18:46.153 に答える
1

いいえ、できないからです。
各アプリは、独自の仮想メモリ空​​間で実行されます。2 つのメモリ空間間でデータを共有することはできません。
また、ロード/アンロードのシーケンスを検討してください。非常に複雑になり、文字列を削除することはできません。
引用の次の部分にも注意してください。

プログラムでプログラムによって宣言または作成された一意の各リテラル文字列。


OK、その MSDN ページをもう少し読んでください。

インターンされた String オブジェクトへの CLR の参照は、アプリケーションまたはアプリケーション ドメインが終了した後も保持できます。

于 2011-07-04T08:19:55.367 に答える
0

Javaに関してはそうです。文字列リテラルは、JVMごとにプールに保持されます。のJavaDocからの抜粋String#intern()All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

于 2011-07-04T08:20:26.510 に答える
0

CLR について理解しているように、AppDomain ごとではなく、ランタイムごとに 1 つです。Jeffrey Richter の「C# 経由の CLR」より

ガベージ コレクターは、内部ハッシュ テーブルが参照する文字列を解放できないことに注意してください。これは、ハッシュ テーブルがこれらの String オブジェクトへの参照を保持しているためです。内部ハッシュ テーブルによって参照される文字列オブジェクトは、AppDomain がアンロードされるかプロセスが終了するまで解放できません。

これは、テーブルが AppDomain から分離されていることを示しています。

JVM にはこの概念がないため、あいまいさはありません。さまざまなクラス ローダーがあるかもしれませんが、String 用にさまざまなクラス ローダーがあるとは想像しがたいです。

于 2013-03-24T18:11:03.323 に答える