2009-07-14 6 views
1

開発者と私のアプリケーションでガベージコレクションされているオブジェクトに問題があります。 Weblogic 10g3でJavaを使用しています。すべてのJMS接続を処理するためのシングルトンパターンをプログラミングしています。これはガベージコレクトされている理由

関与する2つのクラスがあります。

public class JMSObject { 
... 
private MessageProducer _producer; 
private MessageConsumer _consumer; 
... 
// standard get/set procs... etc. 
} 

public class JMSFactory { 
... 
// Hashmap sessions with key == ConnectionFactory Name 
    Hashmap<String, List<Session>> _sessions; 

// Hashmap of JMSObjects with key == ConnectionFactory Name + JMS Queue Name 
    Hashmap<String, List<JMSObject>> _jmsobjects; 
... 
// standard get/set & necessary sington functions 
} 

は、サーブレットのinitメソッドは、新しいセッションがHashMapのと新しいのMessageConsumer /れるMessageProducersがJMSObjectとして作成され、配置されている_sessionsに配置され、JMSFactoryのsingltonメソッドを呼び出します_jmsobjectsハッシュマップの適切なリストに追加します。

問題があるのは、リスト内のJMSObjectsがガベージコレクションをしばらくしてから(時には数時間後に5分になることもある)数日間見ましたが、何も見つかりませんでしたJMSObjectsが収集された着信通知の理由。なぜJMSFactoryはそれらを参照しているのですか?我々は次のようにクラスを変更することによってそれを固定端で

(メソッド・インターフェースを変更せずに):

public class JMSObject { 
... 
private List<MessageProducer> _producers; 
private List<MessageConsumer> _consumers; 
... 
// standard get/set procs... etc. 
} 

public class JMSFactory { 
... 
// Hashmap sessions with key == ConnectionFactory Name 
    Hashmap<String, List<Session>> _sessions; 

// Hashmap of JMSObjects with key == ConnectionFactory Name + JMS Queue Name 
    private Hashmap<String JMSObject> _jmsobjects; 
... 
// standard get/set & necessary sington functions 
} 

これまでJMSObjectsのテストにはgc'edされていません。それは2日間実行されています。

なぜ間接参照によってJMSObjectがgc'edになるのか説明できますか?そして、セッションハッシュマップのセッションがなぜgc'edされていないのですか?セッションはJavax型で構築されているという事実と関係があり、JMSObjectは私たちが書いたものですか?

+0

'JMSObject'がガベージコレクションを取得すると、リストのサイズは同じになりますが、読み込んだときに' null'が返されます。 –

+0

@Jack Leow、Yes NullPointerException ... :-(( – beggs

答えて

2

私はあなたの問題が何であるかを知っていると思いますが、これは私がしばらく前に(WebLogic 6上で)実行したものです。私は、WebLogicがダイナミックなクラスのリロードを行うのは、WebLogicが開発環境にいなくてもそうであるように見えることです(私はweb.xmlが何らかのサービスや何かによって何らかの形で触れられていると推測しています) )。

私たちのケースでは、あなたと同じように、あるクラスの静的変数として定義されているオブジェクトのインスタンスが1つあります。あなたと同じように、起動時の負荷がかかるサーブレットによって初期化されますパラメータセット。 WebLogicは変更があると判断すると、クラスローダー(これは問題ありません)をガベージコレクションしてWebアプリケーションをリロードしますが、 "load-on-startup"とマークされたすべてのサーブレットを再初期化しません私はあなたのことを推測しています。サーブレットは静的変数を初期化する以外の目的はありません。静的変数を初期化する以外の目的はありません。そのため、マッピングできず、静的変数はGCed取得されますが再初期化されず、

私たちのソリューションは、静的初期化子で静的変数を初期化することでした。元の開発者は、サーブレットコンテキスト情報を必要としていたため、変数を初期化するためにサーブレットを使用しました。コンテキスト情報が必要な場合は、ServletContextListenerで初期化を試すことができます。

+0

;興味深いことに、Dynamic Class Reloadingの動作を調べなければなりません。あなたはそれが公平ではないと言っているように聞こえます。新しい実装(2番目のコードブロック)で問題は発生していませんが、根本原因が何であるかを把握する必要があります。ありがとう。 – beggs

+1

私はそれを見ます、そして、それは私がより早く反応しなかった理由の1つです。それは数日間安定しているに過ぎないと言いました。私たちのシステムは、この問題を解決するまでに数週間かかることがあります。 –

+0

2番目のバージョンで問題が発生したので、これが受け入れられましたか? :) –

5

JMSFactoryには参照があるので、なぜgcがそれらを破壊するのでしょうか?

この時点でまだJMSFactoryへの参照を保持しているオブジェクトはありますか?

典型的なシングルトンパターンは静的メンバでシングルトンオブジェクトへの参照を保持します:

public class Singleton { 
    private static Singleton instance = new Singleton(); 

    private Singleton() { 
     //constructor... 
    } 

    public static Singleton getInstance() { return instance; } 
} 

は、これはあなたが以下の通りのパターンではないですか?実際のシングルトンコードを除外したので、あなたのポストで提供したコードから伝えることはできません...

(これは、このようなもののためにシングルトンを使用すると、テストを実行します。Singletons Are Pathlogical Liarsを参照してください)

+0

)@matt b ...はい静的なやや異なるコードです(コンストラクタでシングルトンをインスタンス化しますが、変数は静的です)。リンクしています。 – beggs

+0

投稿しているコードが本当に問題のコードではない場合は、問題を解決するのに少し難しいです... –

+0

商用コードを実際に投稿できません。;-)が違反します企業ルール。 @ Jack Leow; – beggs

0

あなたは_sessionsマップのセッションがGC化されていないと言っていますが、JMSObjectsはそうではありませんでした。あなたが書いたものなので、それは疑わしい。 JMSFactory自体が収集されている(つまり、シングルトンが適切に実装されていない)か、マップからキーを削除しているようです。どちらの場合でも、JMSObjectsはGCの対象となりますが、セッションオブジェクトには参照が残っているため、セッションオブジェクトは対象になりません。

1

コードのすべてを解くことなく、これを解決するのは難しい質問です。しかし、助けるツールがあります。

このリンクを試す:http://blog.emptyway.com/2007/04/02/finding-memory-leaks-in-java-apps/ jhatとjmapの使い方についての情報を提供します。記事はメモリリークを見つけるために書かれていますが、オブジェクトへの参照を追跡する方法に関する情報を提供します。たぶんあなたの参照が消えている理由を追跡することができます。

0

JMSFactoryをロードしたクラスローダーがアンロードされ、JMSFactoryクラスをGC'ed(シングルトンインスタンスを含む)にすると、HashMapsとその内容が解放されます。

関連する問題