7
String str1="JAVA";
String str2="JAVA";
String str3=new String("JAVA");
String str4=new String("JAVA").intern();

2 つのオブジェクトが作成されます。メソッドが同じ値を持つ文字列の文字列プールにチェックインするため、 new 演算子を使用して同じオブジェクトをポイントし、同じオブジェクトをポイントするため、文字列リテラルプールの概念とポイントのために同じオブジェクトstr1を参照します。str2str3str4str1str2intern()

str1=str2=str3=str4=null;

1 つのオブジェクトが GC の対象になります。それが によって作成されたオブジェクトですString str3=new String("JAVA")。最初の String オブジェクトは、文字列リテラル プールに格納された参照を介して常にアクセスできます。

私の説明は正しいですか?

4

1 に答える 1

12

プロセスで作成された文字列オブジェクトの総数?

3: リテラルを介して作成されたインターン プール内の 1 つと、 を介して作成した 2 つnew String

1 つのオブジェクトが GC の対象になります。

私は 2 つ、場合によっては非常に特殊な状況下では 3 つすべてを数えます。

  1. この行で作成したもの:

    String str3=new String("JAVA");
    

    (後で に設定str3したためnull)。

  2. この行で一時的に作成したもの:

    String str4=new String("JAVA").intern();
    

    その行は新しいStringオブジェクトを作成し、internそれを呼び出し、プールから文字列への参照を保存します。したがって、理論的には、StringGC ですぐに使用できるオブジェクトが作成されます。(JVM はそれを行わないほど賢いかもしれませんが、それが理論です。)

  3. おそらく、最終的には、適切な条件の下で、インターンプールの文字列でさえ. 一般に信じられていることとは反対に、この他の質問への回答からわかるように、インターン プール内の文字列はガベージ コレクションに使用できます。permgen に含まれているからといって ( Oracle の JVM 7 以降を使用していない限り) 、permgen も GC されているため、 GC されていないわけではありません。コードで使用されている文字列リテラルがいつ、どのように参照されなくなるのでしょうか。答えはわかりませんが、合理的な仮定は次のようになると思います。それを使用しているクラスがいつメモリからアンロードされるか。この他の答えによると、これは、クラスとそのクラスローダーの両方がアンロードされている場合にのみ発生する可能性があります (それでも発生しない場合があります)。クラスがシステム クラスローダによってロードされた場合 (通常の場合)、おそらくアンロードされることはありません。

したがって、ほぼ確実に 2 つだけ (上記の #1 と #2) ですが、#3 を調べるのも楽しかったです。

于 2013-06-29T07:17:45.740 に答える