2

Web アプリケーションの運用メモリ リークを診断しようとしています。このアプリケーションは、Tomcat 7 および mySQL で実行される GWT アプリであり、Debian では OpenJDK 1.6.0_18 です。

私は tomcat を起動し、アプリを数日間リークさせました (アプリのリロードはありません)。その後、ヒープ ダンプを取得して Eclipse MAT プラグインで開きました。私は自分が見ているものを理解しようとしています。tomcat の loggin クラスから大量のメモリが保持されているようです (下のスクリーンショットを参照)。

Java ロギング フレームワークを使用して、GWT サーブレットで基本的なロギングを行います。のような基本的な呼び出し

Logger.getAnonymousLogger().log(Level.INFO, "User" + userId + " did something interesting");
Logger.getAnonymousLogger().log(Level.SEVERE, exception.getMessage(), exception);

これと同様の問題を Web で見つけたのは、このブログ投稿だけでした。

ここで何が起こっているのか、誰か説明できますか? tomcat ロギング クラスが大量のメモリを保持しているのはなぜですか?

MAT 分析のスクリーンショット

さらに私を混乱させるために、それは大量の弱い参照を保持しているようです-しかし、MATでそれらの弱い参照が何を指しているのかを見つける方法を理解できないようで、弱い参照も期待できますヒープ制限に達したときに収集されますが、代わりに tomcat がメモリ不足の例外をスローします。

弱い参照の巨大な配列

4

1 に答える 1

3

興味深い問題:)

何千万ものクラスが RootLogger にロガーを登録しているようです。ここで、プロジェクトに何百万ものクラスがない限り、次のいずれかを行います。

  • クラスが定期的にLogger.getAnonymousLogger()を呼び出す、または
  • ロガーまたはクラスが動的に生成されています:
    • これらは次のものから来ている可能性があります。
      • java.lang.reflect.Proxy
      • クラスを動的に作成できるスクリプト言語 (Groovy など)
      • バイトコード操作ライブラリ
      • 直通電話new Logger(name)
    • 作成された各クラスはロガーを登録します - LogManager.addLogger()
    • しばらくすると、ロガー (および作成されたすべてのクラス) が GC されます。

いずれにせよ、ロガーを追加するたびに、弱参照を含む ArrayList に別の行が追加されます。弱参照はロガーを指すことから始まりますが、ロガーは GC され、空の弱参照だけが残ります。OOM を引き起こしているのは、それらが (以前は) 指していたオブジェクトではなく、膨大な数の弱い参照です。

修正?

  • 匿名ログを使用している場合は、使用しないでください。これは、アプレットで使用するためのものです。
  • LogManager.addLogger動的クラスにあるかどうかを確認してください。その場合、ロガー名を強制的に定数にします
  • のようなものがないか確認してくださいnew Logger(variable)。その場合は、変数を定数に変更する必要があります。
于 2013-04-09T04:28:32.710 に答える