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 メソッドが JMSFactory シングルトン メソッドを呼び出し、新しいセッションが _sessions ハッシュマップに配置され、新しい MessageConsumer/MessageProducers が JMSObject として作成され、_jmsobjects ハッシュマップの適切なリストに配置されます。

問題は、システムがリスト内の JMSObjects を実行しているときに、しばらくすると (5 分後に、場合によっては数時間後に) ガベージ コレクションが行われることです。これを数日間調べましたが、JMSObjects の理由を見つけることができませんでした。ガベージコレクションされます。JMSFactory にはそれらへの参照があるのに、なぜ gc はそれらを破棄するのでしょうか?

最後に、クラスを次のように変更して修正しました(メソッドインターフェイスは変更しません)。

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 されていません。2日間実行されています。

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

4

5 に答える 5

5

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

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

典型的なシングルトン パターンでは、シングルトン オブジェクトへの参照が静的メンバーに保持されます。

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

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

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

これはあなたがたどっているパターンではありませんか?実際のシングルトンコードを省略したため、投稿で提供したコードからはわかりません...

(ところで、このようなものにシングルトンを使用すると、テストが難しいだけでなく、痛みを引き起こすように聞こえます。シングルトンは病的な嘘つきを参照してください)

于 2009-07-14T03:16:01.053 に答える
2

私はあなたの問題が何であるかを知っていると思います。それは私がしばらく前に遭遇したものです(WebLogic 6で)。これは、開発環境にいないときでも、WebLogic が時々行うように見える、WebLogic の動的クラスの再読み込みに関係していると思います (web.xml が何らかのサービスまたは何かによって何らかの形で影響を受けていると思います)。 )。

私たちの場合、あなたと同じように、あるクラスの静的変数として定義されたオブジェクトの単一のインスタンスがあり、あなたと同じように、起動時にロードするパラメーター セットを持つサーブレットによって初期化されます。WebLogic が変更があると判断すると、クラスローダのガベージ コレクションによって Web アプリケーションをリロードします (これは問題ありません)。あなたの推測では、サーブレットは静的変数を初期化する以外の目的を果たさず、それへのマッピングがないため、呼び出すことができず、静的変数はGCされますが、再初期化されず、サーバーを再起動する必要があります.

私たちの場合、解決策は、静的初期化子で静的変数を初期化することでした。元の開発者は、実際には不要なサーブレット コンテキスト情報が必要だったため、サーブレットを使用して変数を初期化しました。コンテキスト情報が必要な場合は、ServletContextListenerで初期化を試すことができます。

于 2009-07-14T04:25:39.120 に答える
1

すべてのコードがなければ、これは解決するのが難しい質問です。しかし、役立つツールがあります。

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

于 2009-07-14T03:25:17.027 に答える
0

_sessionsマップのセッションはGCされていないとおっしゃいましたが、JMSObjectsはされていませんでした。それはあなたが書いたものだからではないかと思います。JMSFactory自体が収集されている(つまり、シングルトンが適切に実装されていない)か、何かがマップからキーを削除しているようです。いずれの場合も、JMSObjectsはGCに適格ですが、リストにまだそれらへの参照があるため、セッションオブジェクトは適格ではありません。

于 2009-07-14T03:19:05.463 に答える
0

JMSFactory をロードしたクラスローダーがアンロードされ、JMSFactory クラスが (シングルトン インスタンスを含めて) GC され、HashMap とその内容が解放される可能性はありますか?

于 2009-07-14T03:42:00.487 に答える