文字列の使用
文字列は可変ではなく、宣言されると変更できません.変更するたびに新しいstringオブジェクトが作成されます.これは、大量の文字列操作を実行すると、スタックに大量のstringオブジェクトが作成され、より頻繁なゴミ回収をもたらし、プログラムの性能を損なうことを意味します.
この問題を回避するには、StringBuilderクラスを使用して文字列を操作するほか、「文字列留保」も使用できます.
文字列:
文字列の不変性のため、同じ文字列に対してメモリに1つの文字列インスタンスしか残っていない場合、後続で宣言される同じオブジェクトがメモリを指すだけで、文字列の使用率が大幅に向上します.文字列留保はCLR内部にハッシュ・テーブルを作成し、文字列を宣言するときにハッシュ・テーブルに参照があるかどうかを問合せ、ある場合はその参照を返します.そうしないと、文字列をKey、参照をValueとしてハッシュ・テーブルに保存し、文字列の利用率を向上させます.
宣言文字列、毎回新しい参照オブジェクト
上記のコードの実行結果はfalseを出力し、同じ値でも参照が異なり、新しいstringオブジェクトが作成されます.
文字列の使用
文字列はAPI:string.Intern(string str)を使用してstringを取得し、stringのハッシュコードを取得し、内部ハッシュテーブルで完全に同じ一致項目があるかどうかを確認し、既存の文字列参照を返す場合は、新しい文字列を作成し、ハッシュテーブルに追加し、参照を返します.
*文字列のメモリはゴミ回収できます.ゴミ回収器はハッシュ表内の参照を解放できません(AppDomainのアンインストールまたはプロセスの終了を除きます).
Internメソッドのほかにstring.IsInterned(string str)もあります
コード・セグメントから分かるように、IsInternedメソッドはInternと同様に、プール内で完全な一致があるかどうかを探し、ある場合は参照を返します.異なる点は、一致がない場合、Internがハッシュ・テーブルに作成して挿入し、参照を返しますが、IsInternedは一致する文字列が見つからない場合、nullを返します.
要約:文字列の残存は、文字列の頻繁な操作によるパフォーマンス損失を低減しますが、文字列の残存ハッシュ・テーブル内の参照を使用しても、プロセスが終了するまで、文字列がゴミ回収されないことに注意してください.
この問題を回避するには、StringBuilderクラスを使用して文字列を操作するほか、「文字列留保」も使用できます.
文字列:
文字列の不変性のため、同じ文字列に対してメモリに1つの文字列インスタンスしか残っていない場合、後続で宣言される同じオブジェクトがメモリを指すだけで、文字列の使用率が大幅に向上します.文字列留保はCLR内部にハッシュ・テーブルを作成し、文字列を宣言するときにハッシュ・テーブルに参照があるかどうかを問合せ、ある場合はその参照を返します.そうしないと、文字列をKey、参照をValueとしてハッシュ・テーブルに保存し、文字列の利用率を向上させます.
宣言文字列、毎回新しい参照オブジェクト
string str1 = "A";
string str2 = "A";
// CLR 4.0 false
Console.WriteLine(object.ReferenceEquals(str1, str2));
上記のコードの実行結果はfalseを出力し、同じ値でも参照が異なり、新しいstringオブジェクトが作成されます.
文字列の使用
string str1 = string.Intern("A"); //
string str2 = string.Intern("A"); //
// true
Console.WriteLine(object.ReferenceEquals(str1, str2));
文字列はAPI:string.Intern(string str)を使用してstringを取得し、stringのハッシュコードを取得し、内部ハッシュテーブルで完全に同じ一致項目があるかどうかを確認し、既存の文字列参照を返す場合は、新しい文字列を作成し、ハッシュテーブルに追加し、参照を返します.
*文字列のメモリはゴミ回収できます.ゴミ回収器はハッシュ表内の参照を解放できません(AppDomainのアンインストールまたはプロセスの終了を除きます).
Internメソッドのほかにstring.IsInterned(string str)もあります
// ,
String str1 = "abcd";
String str1Interned = String.IsInterned(str1);
//false str1Interned = "abcd"
Console.WriteLine(str1Interned == null);
// ,
String str2 = new StringBuilder().Append("x").Append("y").Append("z").ToString();
String str2Interned = String.IsInterned(str2);
//true
Console.WriteLine(str2Interned == null);
コード・セグメントから分かるように、IsInternedメソッドはInternと同様に、プール内で完全な一致があるかどうかを探し、ある場合は参照を返します.異なる点は、一致がない場合、Internがハッシュ・テーブルに作成して挿入し、参照を返しますが、IsInternedは一致する文字列が見つからない場合、nullを返します.
要約:文字列の残存は、文字列の頻繁な操作によるパフォーマンス損失を低減しますが、文字列の残存ハッシュ・テーブル内の参照を使用しても、プロセスが終了するまで、文字列がゴミ回収されないことに注意してください.