- PR -

static変数は、GCの対象ですか?

投稿者投稿内容
かい
常連さん
会議室デビュー日: 2003/05/27
投稿数: 34
投稿日時: 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/01
投稿数: 13
投稿日時: 2004-09-09 19:20
そもそも、GCの対象になるのは変数ではなくオブジェクトでは?
さく
会議室デビュー日: 2004/09/01
投稿数: 13
投稿日時: 2004-09-09 19:34
引用:

そもそも、GCの対象になるのは変数ではなくオブジェクトでは?


ここで切ったらなに言いたいかわかりませんね。

静的フィールドから参照されているオブジェクトならその静的フィールドが
存在する限りなくなることはないですよね。

で、静的フィールドがなくなる可能性って、クラスがアンロードされること
だと思うのですが、どんな場合があるのでしょうか。すべてのインスタンス
がなくなったとき?

かい
常連さん
会議室デビュー日: 2003/05/27
投稿数: 34
投稿日時: 2004-09-09 20:13
かいです。

返信、ありがとうございます。
少し質問させてください。

引用:

静的フィールドから参照されているオブジェクトならその静的フィールドが
存在する限りなくなることはないですよね。



「静的フィールド」というのは、私のソースの場合、

private static Queue queueMng = new Queue() ;

この行を指していると、理解して良いですか?
となると、GCの対象外ということになり、JVMを終了させない限り、
queueMngは、無くならないということになりますか?

よろしくお願いします。


aa
ぬし
会議室デビュー日: 2004/01/08
投稿数: 299
投稿日時: 2004-09-09 20:39
引用:

GCの対象外ということになり、JVMを終了させない限り、
queueMngは、無くならないということになりますか?


残念ながらそうではありません。
基本的には
コード:
private static Queue queueMng = new Queue() ; 


の場合、「 new Queue() 」されたオブジェクト(インスタンス)は
「queueMng」にヒモ付けされている間はGCの対象にはなりません。
これはstaticかどうか、privateかどうかには関係ありません。

「 new Queue() 」されたオブジェクトがGCの対象となるのは、
現在、どの変数からもヒモ付けされていないという場合です。

ですから今回のご質問の場合、Queue クラス自体がGCの対象になると
「queueMng」にヒモ付けされているものもGCの対象となります。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2004-09-09 21:29
さらにいえば、
queueMng = null;
としたり、
queueMng = new Queue();
としたりすると、queueMngが参照していたオブジェクトはGCの対象になりますね。

というか、気にされていることはなんですか?

あと本題とは離れてしまいますが、

・シングルトンにするならコンストラクタはprivateにしましょう
・enqueue、dequeueメソッドでは排他処理しないとダメですよ
かい
常連さん
会議室デビュー日: 2003/05/27
投稿数: 34
投稿日時: 2004-09-09 22:01
かいです。

aaさん、ukさん、返信ありがとうございます。

引用:

さらにいえば、
queueMng = null;
としたり、
queueMng = new Queue();
としたりすると、queueMngが参照していたオブジェクトはGCの対象になりますね。

というか、気にされていることはなんですか?



static変数に入れている時に、GCの対象になるのかどうか、分からなくて
投稿しました。(過去のJDKのバージョンでは、GCの対象になっていた記事を
見たこともあったので)

ukさんの指摘にあることが行わなければ、GCに対象から外れてるという
ことですね。(ソースで言うと、キューのリストは、残っているということ)

引用:

あと本題とは離れてしまいますが、

・シングルトンにするならコンストラクタはprivateにしましょう
・enqueue、dequeueメソッドでは排他処理しないとダメですよ



指摘して頂き、ありがとうございます。
そのまま、実装してしまうところでした。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2004-09-10 01:04
ある「もの」がGCされるのは、その「もの」を指している「生きた参照」がすべて無くなった後です。

この例の場合ですと、
(1) クラスQueueが生きている限り、そのsingletonインスタンスは生きている。
(2) クラスQueueをロードしたClassLoaderが生きている限り、クラスQueueは生きている。
(3) ClassLoaderがロードしたクラスのインスタンスが一個でも生きている限り、ClassLoaderは生きている。
ということになります。

一般的な認識としては、
(a) 通常のアプリでは、シングルトンがGCされることは気にしなくて大丈夫。
 (すべてのクラスがシステムClassLoaderによってロードされ、システムClassLoader
  は常に生きているから)
(b) サーブレットの場合だと、アプリがアンロードされるとシングルトンも消えてしまう。
 しかし、これは「まさに期待した通りの動作」なので問題ない。

特殊なClassLoaderを自作することがないのであれば、
(≒フレームワークを根本から構築するのでない限りは)
static変数が参照しているオブジェクトのGCを考慮する必要は生じません。

この辺りの議論はかなり難解になりますが、
「それを理解できないプログラマーは、それを気にしなくて良い」
という原則はかなり上手く実現されているのではないかと。

スキルアップ/キャリアアップ(JOB@IT)