- - PR -
ガベージコレクションの対象となるタイミングについて
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-11-19 22:35
解決しました。いろいろとご迷惑おかけし、申し訳なく。回答はガーベッジコレクトにキューされませんでした。今回はいろいろと勉強になった部分があり、感謝いたします。
とりあえず、確認コードを下記にのせておきます。 import java.lang.ref.*; public class Sample{ public static void main(String args[]){ /* Object[] b = new Object[1]; Object a = new Object(); */ String[] b = new String[1]; String a = new String("ABC"); b[0] = a; ReferenceQueue aReferenceQueue = new ReferenceQueue(); WeakReference ref = new WeakReference(a, aReferenceQueue); boolean bool = ref.isEnqueued(); System.out.println("bool 1 : " + bool); a = null; System.gc(); bool = ref.isEnqueued(); System.out.println("bool 2 : " + bool); b[0] = null; System.gc(); bool = ref.isEnqueued(); System.out.println("bool 3 : " + bool); b = null; System.gc(); bool = ref.isEnqueued(); System.out.println("bool 4 : " + bool); System.out.println("Bye"); } } [ メッセージ編集済み 編集者: begood 編集日時 2003-11-19 22:56 ] | ||||||||||||
|
投稿日時: 2003-11-19 23:23
unibon です。こんにちわ。
なるほど。弱参照を使えば確認できるんですね。 なお、その後、String の finalize をオーバライド(String で Object.finalize をオーバライド)するために、 「例外処理Exception につて」 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=6544&forum=12 のように rt.jar を書き換えてみましたが、 String クラスに finalize メソッドを追加したものを実行すると native な部分で落ちてしまい、ダメでした。 ちなみに String クラスのコンストラクタを書き換えて デバッグ用に System.out.println を追加したものなら動きましたが、 でもリテラルはコンストラクタが動かないようでした。 たとえば、
では String b = new String("unibon"); の行ならコンストラクタが動きましたが、 String a = "unibon"; だと動きませんでした。 これってあたりまえのことなのかもしれませんが (言語仕様書を見ていないので良く分からないのですが)。 コンストラクタが動かないのなら、 ガーベッジコレクションの対象にもならないのもなんとなく納得できます。 #ちなみに String クラスはコンストラクタの数が多すぎ。 | ||||||||||||
|
投稿日時: 2003-11-20 03:58
等しい文字リテラルは、クラスが異なっても同じインスタンスを指すので、 VM が終了するまで開放されないはずです。 | ||||||||||||
|
投稿日時: 2003-11-20 07:22
「Java Language Specification - 3.10.5 String Literals」を参照のこと。String a = "unibon";はすでにコンパイル時にプールされてしまいますので、実行時には生成されないはずです。 元々の問題を見ると String a = "ABC"; とあるので、コンパイル時に"ABC"はプールされます。プールの生存期間はStringクラスがアンロードされるまで(現実的にはVM終了まで)なので、明らかに問題は間違っています。答えは、「プログラム終了するまで消されない」だと思います。 参考: 「Tech Tips 1999 1月14日」- http://sdc.sun.co.jp/java/private/techtips/1999/tt0114.html#3 (登録が必要) 「Java Language Specification - 3.10.5 String Literals」- http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#101083 (英語) 「Java API Document − Stringクラス」 | ||||||||||||
|
投稿日時: 2003-11-20 16:06
一応、反証コードを挙げます。 まず、以下のようなコードをコンパイルし、クラスパスの通っていない場所にクラスファイルを配置します。 toString()の戻り値はリテラル文字列です。
次に、以下のようなクラスを作成しコンパイル実行します。 (1)のURLに上のクラスの格納ディレクトリのパスを指定してください。 (2)は作成したクラスローダーからクラスが読み込まれたことの確認です。 (3)はStringオブジェクトがリテラル文字列であることの確認です。
私の環境(Win2000、j2sdk1.4.2)では以下の出力が得られました。 ClassLoader : null Class : null Object : null String : null これはリテラル文字列もGCの対象であることを示すと思います。 まあ、現実的にクラスがアンロードされることなんて滅多にないと思いますけどね。 | ||||||||||||
|
投稿日時: 2003-11-20 16:44
おふとぴー。
ところで、ガベージコレクションで正しいの、ガーベッジコレクションじゃなくて。 Googleの検索結果 ガベージコレクション 7730件 ガーベッジコレクション 1810件 ガベージコレクションの方が正しいのかな。はてな。 # 追加 つづりはgarbageなんすけど。 [ メッセージ編集済み 編集者: かずくん 編集日時 2003-11-20 16:49 ] | ||||||||||||
|
投稿日時: 2003-11-20 16:54
Wataさんの例は、string というオブジェクトが gc されることを示すだけで、"Test" が gc されるかどうかは示していないと思います。
>ところで、ガベージコレクションで正しいの、ガーベッジコレクションじゃなくて。 こちらの発音記号を読んでください。音声でも確認できます。 http://dictionary.goo.ne.jp/search.php?MT=garbage&kind=ej カタカナにするときに微妙に表記が発音とずれることはよくあることですね。 | ||||||||||||
|
投稿日時: 2003-11-20 17:06
このスレッド立てた忍者鳥取県です。 色々みなさまにコメントを頂いているのですが、 内容が難しすぎて全くリアクションができません。 申し訳ありません。m(_ _)mペコリンコ しかし、色々と助言頂きまことにありがとうございます。 (ちなみに、問題2を作成した会社へ問合せしてみましたが、 依然回答は頂いておりません。) かずくんさんへ http://dictionary.goo.ne.jp/search.php?MT=garbage&kind=jn&mode=0&ej.x=45&ej.y=6 こちらで本場の発音体験してみたください。 どうも、本場の発音で言ったらガーベッジが正解っぽい すね。 | ||||||||||||
