[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[jfriends-ml 10315] GC の対象になるのは?
以下の問題がどうしてもわかりません。どなたか解説していただけますか? (_ _)
出展:SUN 教科書 Java 2 (試験番号:310-025)
ビル・ブローデン著、有限会社トップスタジオ 訳編、翔泳社 発行
問題:(210ページ)
問題8-7
次のメソッドでは、カウントダウンの数値を出力するために複数のStringオブジェ
クトが作成されます。
1. public void countDown()
2. for( int i = 10 ; i >= 0 ; i-- ){
3. String tmp = Integer.toString( i );
4. System.out.println( tmp );
5. }
6. System.out.println("BOOM!");
7. }
※1行目に"{"がないのは本の通り。脱字と思いますが。
6行目に処理が進んだ時点で、3行目で作成されたStringオブジェクトのいくつがガ
ベージコレクションの対象となりますか(System.outオブジェクトに参照がないと
仮定します)。
A. なし
B. 1個
C. 10個
D. 11個
解説には、以下の通り書かれています。
解説
正解は選択肢Cです。11個のStringオブジェクトのうち最後の1つだけにまだ参照が
あります。したがって選択肢A、B、Dは不正解です。6行目ではtmp変数はスコープ
の外になりますが、それでもtmpには最後のStringオブジェクトへの参照が格納さ
れています。この点でも選択肢Dは不正解です。
私は、Dかと思いましたが間違いのようです。ん? と思って2つほど実験してみまし
た。
■実験1 javap -c
上記メソッドのみを記述したGcTestクラスをGcTest.javaというファイルに保存し、
コンパイルしてから javap -c してみました。(J2SE SDK v1.3.1_04 on WinNT)
-------------------------------------------------------------
Compiled from GcTest.java
public class GcTest extends java.lang.Object {
public GcTest();
public void countDown();
}
Method GcTest()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 return
Method void countDown()
0 bipush 10
2 istore_1
3 goto 21
6 iload_1
7 invokestatic #2 <Method java.lang.String toString(int)>
10 astore_2
11 getstatic #3 <Field java.io.PrintStream out>
14 aload_2
15 invokevirtual #4 <Method void println(java.lang.String)>
18 iinc 1 -1
21 iload_1
22 ifge 6
25 getstatic #3 <Field java.io.PrintStream out>
28 ldc #5 <String "BOOM">
30 invokevirtual #4 <Method void println(java.lang.String)>
33 return
-------------------------------------------------------------
これを見ると、変数2番にtmpが格納されているようです。行番号10で毎回上書きされ
ていることと、2番にtmpになるもの以外代入されていなさそうなので、「最後の1個
の参照のみが残っている」のか、と理解(?)できなくもないですが…。
■実験2 WeakReferenceを使って参照の確認。
下記プログラムを実行すると、weak1では11個すべて値が保持されており、gc()後の
weak2では11個すべてnullになっていました。ってことは、スコープが外れても参照
が残っている(?)ことはわかりましたが、11個すべてがGCの対象になっているという
ことではないんですかね?
-------------------------------------------------------------
import java.lang.ref.WeakReference;
public class GcTest {
public static void main(String[] args) {
new GcTest().countDown();
}
public void countDown() {
WeakReference[] weak = new WeakReference[11];
for (int i = 10; i >= 0; i--) {
String tmp = Integer.toString(i);
weak[i] = new WeakReference(tmp);
System.out.println(tmp);
}
System.out.println("weak1:");
for (int i = 10; i >= 0; i--) {
System.out.println("weak[" + i + "]=" + weak[i].get());
}
System.gc();
System.out.println("weak2:");
for (int i = 10; i >= 0; i--) {
System.out.println("weak[" + i + "]=" + weak[i].get());
}
System.out.println("BOOM");
}
}
-------------------------------------------------------------
実行結果:
10
9
8
7
6
5
4
3
2
1
0
weak1:
weak[10]=10
weak[9]=9
weak[8]=8
weak[7]=7
weak[6]=6
weak[5]=5
weak[4]=4
weak[3]=3
weak[2]=2
weak[1]=1
weak[0]=0
weak2:
weak[10]=null
weak[9]=null
weak[8]=null
weak[7]=null
weak[6]=null
weak[5]=null
weak[4]=null
weak[3]=null
weak[2]=null
weak[1]=null
weak[0]=null
BOOM
-------------------------------------------------------------
---------------------------------------------------
(株)PFU システム事業部ソフトウェア統括部第二開発部
福嶋 航 w.fukushima@xxxxxxxxxxxxxxx