1

私のアプリケーションは、クラス A などのクラスのインスタンスを多数作成します。すべてのインスタンスには文字列が含まれており、それらのほとんどには同じ文字列が含まれています。

class A {
   String myString;
}

JVMは「すべての等しい文字列」を、一度だけ格納された同じ文字列を指すようにすることを知っています。私の A インスタンスの 1 つの myString フィールドが上書きされた場合、元の文字列への参照が新しい文字列値への参照に置き換えられ、すべてが期待どおりに機能します。

この動作は準拠している JVM に必要ですか、それとも jvm から別のバージョンへ、またはバージョンからバージョンへと変更される可能性のある jvm の一種の改善ですか?
別の言い方をすれば、非常に冗長な (文字列ベースの) データ構造を設計する場合、コピー オン ライト メカニズムだけに頼るべきか、それともアプリケーション レベルで何かを配置することをお勧めしますか?

4

3 に答える 3

1

これのもう 1 つの側面は、文字列が動的に作成された場合 (たとえば、パーサーによって割り当てられた場合)、文字列が同じにならないことです。スペースが問題になる場合は、 String.intern() を確認してください。

String a = String.valueOf('a') + "b";
String b = a.intern();
String c = "ab";
// now b == c is true
于 2012-09-02T22:01:03.153 に答える
0

実は、String は通常のオブジェクトです。

String a = "test";
String b = a;

以下とまったく同じことを行います:

StringBuffer a = new StringBuffer("test");
StringBuffer b = a;

つまり、どちらの場合も、b は a への 2 番目の参照であり、これは不変性によるものではありません。

不変性の登場
したがって、常に同じデータへの 2 つのポインターを処理します。クラスが不変である場合は、そのことを忘れて構いません。自分用のコピーがあるからではなく、共有コピーが不変だからです。文字列のコピーがあると考えることもできますが、実際には文字列 b = a; 以降、コピーは存在しませんでした。各オブジェクトに対して行うこと、つまり唯一の参照のコピーを行います。

于 2012-09-03T10:23:10.267 に答える
0

@Hot Licksが言ったように:文字列は不変であるため、コピーオンライトについて話す場所はありません。また、可変オブジェクトを使用している場合は、クライアントの環境で「書き込み時にコピー」を使用できない場合があることに注意する必要があります。

そして、たくさんのオブジェクトを作成するときに非常に重要になる可能性のあるもう 1 つのことです。各オブジェクトには、数バイトのヘッダー、ポインターなどが含まれています。正しく覚えていれば、空のオブジェクトは20バイト程度です。プロパティを含む多くのオブジェクトについて話していると、それが重要になり始めます。そのことに注意し、それが問題の原因であることを測定したら、アプリケーション レベルで何かを行う必要があります (軽量設計パターン、ストリーム xml パーサーの使用など)。

于 2012-09-02T21:54:59.553 に答える