ホームページ  >  記事  >  Java  >  Javaメモリの異常使用によるフルGCが多発する問題の解決方法

Javaメモリの異常使用によるフルGCが多発する問題の解決方法

WBOY
WBOY転載
2023-05-16 12:31:111473ブラウズ

問題のシステム

毎日の検査により、アプリケーション行に頻繁にフル gc が表示されることが判明しました

現象

アプリケーション行に頻繁にフル gc が表示されました


Javaメモリの異常使用によるフルGCが多発する問題の解決方法

トラブルシューティング プロセス

ダンプの分析

ダンプ ファイルをプルします: 間奏: ダンプ時に:live を指定すると、JVM はダンプの前に最初にそれを実行します。 dumping full gc, and dump full gc will print in the gc log. メモリ リークが原因ではないオンラインの異常なメモリ状態に対するこの種のトラブルシューティングは不便をもたらし、何度かダンプを行うことになります。

ダンプ ファイルを分析します:

a. 多数の long[] 配列が最大スペースを占有しており、例外もあります


Javaメモリの異常使用によるフルGCが多発する問題の解決方法

b . gc ルート ノードを確認すると、これらの long[] データのほとんどが org.HdrHistogram.Histogram によって保持されていることを確認します。各 Histogram オブジェクトは 2048 サイズの long[]

を保持します。 c. Histogram インスタンスの数を確認します。実際には 50,000 個あります。通常のプロジェクトのスタックと比較すると、約 100 倍です。


Javaメモリの異常使用によるフルGCが多発する問題の解決方法

d。これは次のとおりです。別のエピソードです。最初は mat 分析を使用していました。しかし、mat で生成されたレポートはリークの分析に役立ちます。異常なメモリの分析には、jvisualvm.exe やアイデア プロファイラー

# ほど使いやすいわけではありません。 ##トラブルシューティングの理由

ローカルで開始すると、このタイプのメモリ使用量を再現できるため、通常のメモリと問題のあるアプリケーションを使用してローカル サービスを開始し、メモリの比較を分析します

アイデアのプロファイラーここでは非常に便利な を使用しています。

違いを発見してください:

正常なアプリケーションと比較すると、異常なアプリケーションの参照には


# からの異常な参照があることがわかります。 Javaメモリの異常使用によるフルGCが多発する問題の解決方法
Javaメモリの異常使用によるフルGCが多発する問題の解決方法#● rx.internal.operators.OnSubscribeReduceSeed$ReduceSeedSubscriber。これだと思います。異常な参照が、これらのインスタンスが新しい世代ではリサイクルできないのに、古い世代では蓄積されてしまう理由です。 trigger full gc

差異のトラブルシューティング:

関連するコードをざっと見ただけでは、理由がわかりません。直接デバッグ比較

システムは確かに通常のアプリケーションには


Javaメモリの異常使用によるフルGCが多発する問題の解決方法# がありませんが、見ただけでは理由がわかりません。左下隅のスレッド プールに追加します。このスレッド プールは非常に奇妙です。これは Metric のスレッド プールです。

Metric は、Hystrix が独自のダッシュボードやユーザーが取得する関連指標をカウントするために使用されます。システムサーキットブレーカー パラメーターとインジケーターの機能

スタックをもう一度見ると、ここに到達するロジックは次のとおりです


Javaメモリの異常使用によるフルGCが多発する問題の解決方法このストリームはシステムをカウントするために使用されます

ヒストグラム自体は、単位時間あたりのトラフィックをカウントするためのバケット スライディング ウィンドウのような関数を実装するために Hystrix によって使用されます。ただし、インジケーター パラメーターがオンになっているため、hystrix より長い時間範囲でインジケーターをカウントするために、新しいオブジェクトは集計用により多くのヒストグラム参照 (単位時間) を保持します。これらの参照は、より長い時間範囲の期間をカウントするために使用されるため、参照が長時間保持されるため、長時間保持されます。古い時代では、本質はメモリ リークではないため、フル gc のたびにリサイクルできます。


解決策

私の最初の反応は、上記の違いと奇妙なスレッド プールを見たときでした。それは、アプリケーションがこのロジックへの参照を追加しないようにメトリックをオフにすることです。公式ドキュメントによると、この構成はデフォルトでオンになっています。そして、この機能がインジケーターの統計にのみ影響し、サーキット ブレーカー自体の機能には影響しないことを確認します。構成 hystrix.metrics.enabled=false を使用して閉じます。

構成を追加した後、スタックを確認して表示します。参照は正常に戻り、一定期間が経過してもシステムはヒストグラム インスタンスを追加しません。オンラインでリリースして一定期間観察した後、完全な gc 問題は実際に解決されました。


根本原因

解決策を見つけて検証した後、hystrix.metrics.enabled のデフォルト設定が true であるにもかかわらず、他のアプリケーションではこの完全な gc 問題が発生しない理由を調査する時間がありませんでした。まずそれを解決してください。その後、他のプロジェクトで同じ問題が発生するのを防ぐために根本原因の調査を継続してフォローアップします。

以前に発見された疑わしいスレッド プールは HystrixMetricsPoller です。検査後、スレッド プールは HystrixMetricsPollerConfiguration で構成されています


Javaメモリの異常使用によるフルGCが多発する問題の解決方法 このクラスは有効になっており、主に hystrix.metrics.enabled に依存していますが、デフォルトは true です。他のプロジェクトが有効になっていないのはなぜですか?

ソースコードを検索した結果、このクラスの開始部分はアノテーションに関連しています。


Javaメモリの異常使用によるフルGCが多発する問題の解決方法

コードを比較したところ、異常な部分のみが判明しました。アプリケーションはこのアノテーションを使用しています。このアノテーションの目的は、サーキット ブレーカーをオンにすることです。

しかし、調査の結果、このアノテーションを使用しなくても、サーキット ブレーカーなどの機能は利用できることがわかりました。その理由は、 spring-cloud バージョンでは、spring は hystrix を使用して openfeign をカプセル化します。hystrix システム全体を統合する代わりに、spring-cloud は hystrix のメモリ使用量の問題も発見した可能性があります。

したがって、より高いバージョン (少なくとも私たちのバージョン) では、 feign は、feign.hystrix.enabled サーキット ブレーカーによってオンとオフが切り替えられます (このスイッチがオフになっている場合、@EnableCircuitBreaker アノテーションをサーキット ブレーカーに追加するだけでは効果がありません)

実際、 spring-cloud では、@EnableCircuitBreaker アノテーションが廃止としてマークされています。しかし、おそらく中間バージョンであるため、放棄されたものとしてマークされておらず、実際には役に立たない状況もあります。

要するに、サーキット ブレーカーfeign の機能は @EnableCircuitBreaker アノテーションを追加した後、feign.hystrix.enabled によってのみ制御されます。他のすべてのインジケーターと Hystrix


Javaメモリの異常使用によるフルGCが多発する問題の解決方法

の他の機能が開くだけです。

以上がJavaメモリの異常使用によるフルGCが多発する問題の解決方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。