- - PR -
static変数は、GCの対象ですか?
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-09-09 18:59
かいです。
static変数は、GCの対象となることがあるのでしょうか? OS:Windows2000 JDK:1.4 public class Queue { private static Queue queueMng = new Queue() ; private Vector queue = new Vector(); public Queue getInstance() { return queueMng ; } public boolean empty(){ return queue.isEmpty(); } public Object enqueue(Object elem){ queue.addElement(elem); return elem; } public Object dequeue() throws Exception{ if(empty()) { throw new Exception("Queue Empty"); } Object elem = queue.elementAt(0); queue.removeElementAt(0); return elem; } } 上記のようなSingltonのクラスを作成した時、GCの対象となって、 キューの内容が消えてしまうことがあるのでしょうか? よろしくご教授ください。 | ||||||||
|
投稿日時: 2004-09-09 19:20
そもそも、GCの対象になるのは変数ではなくオブジェクトでは?
| ||||||||
|
投稿日時: 2004-09-09 19:34
ここで切ったらなに言いたいかわかりませんね。 静的フィールドから参照されているオブジェクトならその静的フィールドが 存在する限りなくなることはないですよね。 で、静的フィールドがなくなる可能性って、クラスがアンロードされること だと思うのですが、どんな場合があるのでしょうか。すべてのインスタンス がなくなったとき? | ||||||||
|
投稿日時: 2004-09-09 20:13
かいです。
返信、ありがとうございます。 少し質問させてください。
「静的フィールド」というのは、私のソースの場合、 private static Queue queueMng = new Queue() ; この行を指していると、理解して良いですか? となると、GCの対象外ということになり、JVMを終了させない限り、 queueMngは、無くならないということになりますか? よろしくお願いします。 | ||||||||
|
投稿日時: 2004-09-09 20:39
残念ながらそうではありません。 基本的には
の場合、「 new Queue() 」されたオブジェクト(インスタンス)は 「queueMng」にヒモ付けされている間はGCの対象にはなりません。 これはstaticかどうか、privateかどうかには関係ありません。 「 new Queue() 」されたオブジェクトがGCの対象となるのは、 現在、どの変数からもヒモ付けされていないという場合です。 ですから今回のご質問の場合、Queue クラス自体がGCの対象になると 「queueMng」にヒモ付けされているものもGCの対象となります。 | ||||||||
|
投稿日時: 2004-09-09 21:29
さらにいえば、
queueMng = null; としたり、 queueMng = new Queue(); としたりすると、queueMngが参照していたオブジェクトはGCの対象になりますね。 というか、気にされていることはなんですか? あと本題とは離れてしまいますが、 ・シングルトンにするならコンストラクタはprivateにしましょう ・enqueue、dequeueメソッドでは排他処理しないとダメですよ | ||||||||
|
投稿日時: 2004-09-09 22:01
かいです。
aaさん、ukさん、返信ありがとうございます。
static変数に入れている時に、GCの対象になるのかどうか、分からなくて 投稿しました。(過去のJDKのバージョンでは、GCの対象になっていた記事を 見たこともあったので) ukさんの指摘にあることが行わなければ、GCに対象から外れてるという ことですね。(ソースで言うと、キューのリストは、残っているということ)
指摘して頂き、ありがとうございます。 そのまま、実装してしまうところでした。 | ||||||||
|
投稿日時: 2004-09-10 01:04
ある「もの」がGCされるのは、その「もの」を指している「生きた参照」がすべて無くなった後です。
この例の場合ですと、 (1) クラスQueueが生きている限り、そのsingletonインスタンスは生きている。 (2) クラスQueueをロードしたClassLoaderが生きている限り、クラスQueueは生きている。 (3) ClassLoaderがロードしたクラスのインスタンスが一個でも生きている限り、ClassLoaderは生きている。 ということになります。 一般的な認識としては、 (a) 通常のアプリでは、シングルトンがGCされることは気にしなくて大丈夫。 (すべてのクラスがシステムClassLoaderによってロードされ、システムClassLoader は常に生きているから) (b) サーブレットの場合だと、アプリがアンロードされるとシングルトンも消えてしまう。 しかし、これは「まさに期待した通りの動作」なので問題ない。 特殊なClassLoaderを自作することがないのであれば、 (≒フレームワークを根本から構築するのでない限りは) static変数が参照しているオブジェクトのGCを考慮する必要は生じません。 この辺りの議論はかなり難解になりますが、 「それを理解できないプログラマーは、それを気にしなくて良い」 という原則はかなり上手く実現されているのではないかと。 | ||||||||
