C((zhi文字列)メモリ割り当てと駐留池学習の共有


ちょうどC〓〓〓を学ぶことを始めます時、CLRはString種類に対して1種の特別なメモリ管理の構造があると聞きました:時には、明らかに2つのString種類の対象を声明して、しかし彼らはどうしても同一の実例を指します。以下のとおりです

String s1 ="Hello";
String s2 ="Hello";                      
//s2 s1 Hello
bool same = (object) s1 == (object) s2;
// s1、s2
// bool same = s1 == s2;
// String == String
ここのsameはtrueに割り当てられます。つまりs 1は本当にs 2と同じStringオブジェクトを引用しています。もちろん、s 1とs 2は同じ文字列のハローに統一されています。これが上記のような理由です。
ここでは、複数の文字列変数が同じ文字列の実際値を含む場合、CLRはメモリを繰り返し割り当てるのではなく、すべて同じ文字列オブジェクトのインスタンスを指すようにするという結論を初歩的に示している。ここで私が言ったのは、いくつかの場合、確かに同じ文字列の実際値がメモリに複数のコピーが同時に存在するからです。続けてみてください。)
String類には多くの特別なところがあると知っていますが、その中の一つは変わらないものです。これは、Stringオブジェクトを操作するたびに(例えばTrim,Replaceなどの方法を使用して)このStringオブジェクトのインスタンスを本当に修正するのではなく、新しいStringオブジェクトのインスタンスを動作実行の結果として返すことを示している。Stringオブジェクトのインスタンスが生成されると、死ぬまで変更されません。
String類という特性に基づいて、CLRは同じ文字列の実際値を示す変数を同一のString事例に向けることが完全に合理的である。Stringのインスタンスの参照を利用した修正動作は、いずれもこのインスタンスの状態に確実に影響を及ぼさないので、そのインスタンスを指す他のすべての参照が表す文字列の実際の値に影響を与えない。CLRはString類のメモリ割り当てをこのように管理し、メモリの使用状況を最適化し、メモリに冗長なデータが含まれないようにする。
このメカニズムを実現するために、CLRは、滞留池(Intern Pool)という表を黙々と維持している。この表には、コード内で文字列量で宣言されたすべての文字列の例の参照が記録されています。これは文面量声明を使った文字列が滞留池に入ることを示していますが、他の方法で宣言された文字列は入らないので、CLRが文字列の冗長性を防止するメカニズムのメリットを自動的に享受することはできません。これは上記のいくつかの場合、確かに同じ文字列の実際値がメモリ内に複数のコピーが同時に存在する例である。この例を見てください。

StringBuilder sb =new StringBuilder();
sb.Append("He").Append("llo");


string s1 ="Hello";
string s2 = sb.ToString();

bool same = (object) s1 == (object) s2;

このとき、sameはtrueではありません。s 1,s 2は同じ文字列を表していますが、s 2は文字どおりの量で宣言されていませんので、CLRはsb.ToStringメソッドの戻り値にメモリを割り当てたとき、プールにHelloという文字列が既に存在しているかどうかをチェックしません。プログラマが強制的にCLRにプールの存在を確認させ、冗長な文字列のコピーを回避するために、String類の設計者はInternというクラスの方法を提供する。以下はこの方法の一例である。

StringBuilder sb =new StringBuilder();
sb.Append("He").Append("llo");


string s1 ="Hello";
string s2 = String.Intern(sb.ToString());

bool same = (object) s1 == (object) s2;

はい、私はまたtrueです。Intern法はパラメータとして文字列を受け入れ,パラメータが表す文字列が存在するかどうかをプールに確認する。存在する場合は、その池にある文字列の参照を返します。そうでない場合は、同じ値を表す新しい文字列をプールに追加し、この文字列の参照を返します。ただし、Internメソッドが滞留池で同じ値の文字列を見つけても、一度に文字列メモリに割り当てられた操作を省くことはできません。パラメータとしての文字列はメモリに割り当てられていますので、注意してください。Intern法を使用する利点は、Intern法が常駐池に同じ値の文字列を見つけた場合、この文字列のコピーがメモリに2つ存在しますが(一つはパラメータで、一つはプールにある)、時間が経つにつれてパラメータが使用するコピーはごみによって回収されます。このように文字列メモリに冗長性は存在しません。あなたのプログラムにはある方法があります。コンテキスト環境に応じて長い文字列を作成して返すことができます。プログラムの実行中には常に同じ文字列を返すことがあります。Internメソッドを使ってメモリの利用率を向上させることを考慮する必要があります。しかし、同様に注意すべきなのは、Intern方法を使用して一つの文字列を駐留池の中に生存させる副作用があることである。他の引用が存在しなくても、滞留池の中の文字列を指す。この文字列はゴミによって回収されるとは限らない。つまり、池にある文字列がもう役に立たなくても、CLRが終わってから廃棄されるかもしれません。Intern法を使う時も、この特殊な行為を考慮しなければなりません。