2017-08-16 13 views
1

現在、私たちのウェブサービスとウェブアプリケーションを、Log4j 2.6ロギングを使用するように移行しています。 Webアプリケーションで提供される情報に基づいて、Webアプリケーションは部分的なガベージ・フリー・ロギングをサポートし、メモリリークの可能性があるためガベージ・フリーのロギングを完全にサポートしません。 TreadLocalを1番目のケースで有効にし、2番目のケースでThreadLocalを無効にすると、ロギングの仕組みを理解できるようになります。なぜlog4j gcフリーロギングがウェブアプリケーションに適していないのですか

また、部分的なガベージ・フリー・ロギングが完全なガベージ・フリー・ロギングよりも優れているシナリオがわかります。

答えて

0

ガーベッジフリーモードでは、Log4j2はLogEventオブジェクトを再利用します。同時に複数のスレッドが同じLogEventを変更しないようにするため、各スレッドには独自のLogEventがあります。これはThreadLocalで実装されています。

ThreadLocalsの重要なポイントは、明示的に削除されるかスレッドが終了するまでは、そこに置かれているものがそのまま残ります。 LogEventへの他の参照がない場合でも、ThreadLocalにはまだ参照があり、スレッドはGCのルートであるため、ガベージコレクションは行われません。

Webアプリケーションコンテナは、多くの場合、カスタムクラスローダーでWebアプリケーションをロードします。これにより、Webアプリケーションコンテナを再起動することなく、異なるバージョンのWebアプリケーションを停止して再読み込みすることができます。ただし、以前のバージョンのWebアプリケーション、そのクラス、およびカスタムクラスローダーを含むすべての関連クラスへの参照がまだガベージコレクションされていない場合、

これはいつ発生しますか? WebアプリケーションコンテナにWebアプリケーション間で共有されるスレッドプールがあり、Webアプリケーションの再読み込み時にフラッシュされないとき。プール内のスレッドには、LogEventオブジェクトと以前のバージョンのWebアプリケーションのクラスに対するThreadLocal参照が残っているため、このクラスはガベージコレクションできず、メモリリークが発生します。 Webアプリケーションがリロードされると

  1. スレッドプールは、Webアプリケーション
  2. の間で共有されていません。次の条件の両方に該当する場合は、Webアプリケーションではごみの無料ロギングを使用することができます

    結論 そのスレッドプールもシャットダウンして再起動します

上記の両方が当てはまる場合は、Log4j2が危険な無駄なログを使用するように設定することができますメモリリークを引き起こします。もちろん、デューデリジェンスとテストをする必要があります。

関連する問題