2013-09-16 4 views
9

誰もが、私はちょうど弦楽のための.NET Frameworkのいずれかの予約メモリがあるかどうかを理解しようとしています.NET Frameworkの文字列オブジェクトに直接ヒープメモリに文字列定数メモリプールC#で

に保存されていることを知っています。 Javaでは、文字列が初期化され、ヒープメモリ内の他のオブジェクトと同様にガベージコレクトされるSCMP(String Constant Memory Pool)という文字列用の予約メモリがあります。

+1

昔はメモリが限られていたモバイルデバイスがあったので、Javaにはこのような機能があると思います。今はそのような機能は必要ありません。コンパイラとガベージコレクタにとってははるかに簡単です。 –

+0

関連するhttp://stackoverflow.com/questions/372547/where-do-java-and-net-string-literals-reside/372559#372559 –

答えて

2

.NETのリテラル文字列は、各リテラル文字列のコピーが1つだけになるように "interned"です。

は私がネットでそのようなものがあると思ういけない

+0

この回答は誤解を招くものです。 *リテラル*文字列は使用できません。動的に構成された文字列は、通常のオブジェクトとしてヒープに割り当てられ、必ずしも一意ではありません。簡単な例: 'Object.ReferenceEquals(" abc "、" ABC ".ToLowerInvariant())は、最初の文字列のみがインターンされるので、' false'と評価されます。 – Douglas

+0

@Douglas - 誤解する意図はありません。答えは、各*リテラル*文字列のコピーが1つあることを示します。引用されたMSDNの参考文献は、あなたが 'String.Intern'メソッドを使用してそれらを強制的に中断させない限り、プログラムで構築された文字列が保留されていないことを非常に明確にしています。 –

+1

また、文字列がインターナショナルであるという理由だけで、文字列メモリが別々に割り当てられた場所にあるわけではありません。通常のヒープメモリーに入れることはできません。要点は、コンパイラがそれらの文字列をすべて追跡し、すべてのリテラルに対して同じ参照が使用されていることを保証することです。別のメモリプールに入れる必要はありません。 – Servy

5

http://msdn.microsoft.com/en-us/library/system.string.intern.aspxを参照してください。 CLRは、テーブルは、プログラム内 リテラル文字列が含まれているインターンプールと呼ば維持

は、代わりに私がthisと文字列が使用されているかの興味深いを読みました。これにより、コード内の同じ定数文字列を繰り返し使用すると、同じ文字列 が使用されます。 System.Stringクラスは、 という文字列がインラインプール内にあることを保証するInternメソッドを提供し、 への参照を返します。

また、このMSDNチェック: - 私たちは、マネージヒープが 同じ文字列を何千回も繰り返し含まれている多数のシナリオを見てきました

を。その結果、多くのメモリが文字列によって消費される大きな作業 が設定されます。この ような状況では、それはstring interning.

1

を利用するほうが良いことが多い.NET FrameworkがIntern Pool、テーブル内の文字列のストレージを節約します。あなたは、表示されることがあります。あなたが1つのコンパイル単位内の2つの同一の文字列リテラルを使用している場合

String interning and String.Empty - Eric Lippert

は、 我々が生成するコードは、1つの文字列オブジェクトが によってリテラルのすべてのインスタンスのCLRを作成されることを保証しますアセンブリ内でこの の最適化は「文字列インターン」と呼ばれます。

String Interning .Net framework

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