Apps原文はこちら。leakJavaにおけるメモリ周りのトラブルシューティングは、よく議論されているトピックです。既存のブログ記事には多くの情報がありますので、なぜ別の記事を書くのかと疑問に思うかもしれません。実際、多くのブログ記事では、さまざまなツールやテクニックが紹介されています。驚くべきことに、そこにある情報の多くは深みに欠け、体系的な見解を提供しておらず、方法論を提供していません。そのため、開発者がこれらの知識を使って実際の問題を解決することは難しいのです。これは、Javaにおける現実のメモリ問題の発見と修正についての2回シリーズの第1回目の投稿です。この記事では、メモリ問題をトラブルシューティングするためのツールや方法論を紹介します。見つけたメモリ問題を修正する方法と、本番環境でのトラブルシューティングを処理する方法について説明します。Appshttps://engineering.salesforce.com/fix-memory-issues-in-your-java-apps-c261046bae52https://logico-jp.io/2021/01/05/fix-memory-issues-in-your-java-apps/このブログ記事では、以下の方法を学びます。Leaksメモリリークとは何でしょう?メモリリークは、アプリケーションで使用されていないにもかかわらず、ガベージコレクタでメモリから削除できないオブジェクトがある場合に発生します。ガベージコレクタ(GC)が参照されたオブジェクトを削除できないので、より多くのメモリリソースが消費され続けます。組み込みのガベージコレクションです。Javaプログラムが実行されると、ヒープにオブジェクトが作成されます。ガベージコレクタは、ヒープ内のすべてのメモリ割り当てを追跡し、使用されていないオブジェクトを自動的に削除します。ガベージコレクションは非常に優れた機能を持っていますが、絶対確実というわけではありません。ガベージコレクションがあるにもかかわらず、メモリリークすることがあります。C++とは異なり、Javaのメモリリークの問題は、メモリ割り当ての追跡を失うことではなく、不要になったオブジェクトが不必要にヒープ内で参照され、ガベージコレクタがそれらを削除できなくなるために発生します。メモリリークを発見するためのツールやテクニックを見てみましょう。leakメモリリークを検出するには、2つの方法があります。1つ目は、アプリがクラッシュしてログやコンソール出力にOutOfMemoryError例外が表示されるまで待つ、というものです。genスペースサイズの傾向をチェックすることです。genスペースは長寿命のオブジェクトのために予約されています。genスペースは、メジャーGCの後にクリーンアップされるべきです。genスペースが増え続けているのであれば、ほとんどの場合、アプリケーションにメモリリークがある可能性が高いです。model”(Javaメモリモデルを理解する)の記事を参照してください。Modelhttps://medium.com/platform-engineer/understanding-java-memory-model-1d0863f6d973JVM設定を使ってGCログを有効にし、プロファイラをアタッチしてJVMメモリ使用量を取得するか、アプリケーションから直接JVMメトリクスを測定できます。Leaksメモリリークの原因はたくさん考えられます。ここでは、最も典型的なものを紹介します。Javaの記事をチェックしてください。Issuesこのセクションでは、アプリケーションの現在のJVM設定、メモリダンプファイル(スナップショット)、ネイティブスペースでのJVMのメモリ割り当てなど、トラブルシューティングに不可欠なデータを収集するための便利なツールをいくつか紹介します。すべてのメモリ問題に適用できる一般的なトラブルシューティング戦略も紹介します。高負荷の本番環境でのメモリリークをトラブルシューティングするために、その他にもいくつか提案できるものがあります。Production”セクション)をチェックしてください。toolboxJVMのメモリに関連する問題をトラブルシューティングするための有用なツールをご紹介します。settings調査を開始する前に、まずアプリケーションの現在のJVM設定(最大、最小ヒープサイズ、metaspaceのサイズ、GCリサイクル時間やリサイクルratioなど)を確認したいものです。これらの設定はアプリケーションパフォーマンスを調べる上で重要です。アプリケーションのJVM設定はコマンドラインツールjpsを使って取得できます。このツールは対象システムの全ての測定可能なJVMをリスト化します。snapshotjmapという別のツールを使って、1個のJVMプロセスのヒープのメモリレイアウトの詳細(メモリダンプもしくはスナップショットとも呼ばれます)を出力しましょう。これもまたコマンドラインツールなので、リモートサーバーで実行できます。createdjmapを使って1個のJVMプロセスのオブジェクトヒストグラムを出力することもできます。このヒストグラムから、どれほどのメモリを異なる種類のオブジェクトが利用しているかがわかります。スナップショットと比べて、軽量かつ高速に収集できますが詳細な情報を収集できるわけではありません。いえ、JVMプロセスの環境がメモリ上で短期間の場合は有用です。heapメモリプロファイラは、ヒープの中を見ることができるように設計されています。以下のように説明しています。Profilerは、Javaバイトコードの構成と操作をJVMレベルで監視するツールです。これらのコード構成と操作には、オブジェクトの作成、反復実行(再帰的呼び出しを含む)、メソッドの実行、スレッドの実行、およびガベージコレクションが含まれます。https://www.baeldung.com/java-profilers実際には、プロファイラは、Javaのメモリ関連の問題をトラブルシューティングする際に最も頻繁に使用されるツールです。ヒープダンプファイルを調べたり、プロファイラをプロセスにアタッチしてライブ・デバッグを行うことができます。プロファイラは、JVMの詳細(GC、メモリ割り当て、スレッド、CPU)を追跡し、その情報を素敵なUIに整理してくれるため、トラブルシューティングがしやすくなります。この記事ではYourkitプロファイラを使用していますが、ここで紹介したスキルはどのプロファイラにも適用できます。usageヒープ以外にも、JVMはスレッドスタック、コード、シンボルなどのためにネイティブメモリを占有します。ヒープが問題なさそうに見えたら、JVMによるネイティブメモリの使用状況(metaspace、スレッドスタックのサイズなど)をチェックしてみましょう。ネイティブ・メモリ・トラッキング(NMT)は、JVMがネイティブ・メモリ空間でどのように動作するかを調べるためのツールです。NMTの使い方は簡単です。JVMの設定で-XX:NativeMemoryTrackingというフラグを追加し、jcmdで結果を確認するだけです。summaryNMTはサードパーティのネイティブコードやJDKクラスライブラリを追跡しないことに注意してください。その名前から、アプリケーションのすべてのネイティブメモリ割り当てを追跡していると思われるかもしれませんが、そうではないため、紛らわしいかもしれません。JNIライブラリを使用している場合、グラフやセッション用のモデルをロードする際に多くのネイティブメモリを消費しますが、これらのオブジェクトはすべてNMTによって追跡されません。この手の問題を解決する方法を説明しています。troubleshootingここでは、トラブルシューティングに役立ついくつかの提案されたJVM設定を紹介します。セクションを参照してください)。各GCアクティビティの後のアプリケーションのメモリステータスがメモリリークがあるかどうかを示す可能性があるため、GCログを有効にすることは非常に重要です。LeakツールやJVMの設定を熟知したあとは、以下の手順でアプリケーションのトラブルシューティングをしましょう。scenarios.(アプリケーションコードとユーザーシナリオの熟知)プロファイラが発見した症状をコード内の根本原因と相関させるには、アプリケーションのコードに精通している必要があります。通常、プロファイラを使用する前にコードを読み込んで主要なワークフローをトレースします。することで、ラージ・オブジェクトやデータ・バッチ・オブジェクトがどこで作成され、メモリ内で参照されているかを認知できます。Model”をご覧ください)。[スナップショット]を取得)jmapコマンドを使ってデバッグ前にスナップショットファイルを作成します。app.(アプリでリソースヘビーな操作を実行)いくつかの高負荷シナリオでアプリケーションを動かします。10個のデータセット(各20GB)をアップロードします。genスペースが増え続けていることがわかった場合、それはメモリリークの明確な兆候です。genスペースを表しています。gen(オレンジ)へと移動し、決して解放されていないことがわかります。これはメモリリークの明確なサインです。GCを引き起こすために非常に便利な強制GC機能を提供しています。genの使用率を取得できます。GC後も参照されている、最も増えたオブジェクトを見つけます。View(到達性ビュー)から探し始めます(下の例を参照)。分からない場合は、2回目のヒープダンプとステップ3で取得した最初のヒープダンプを比較してみてください。referenceをチェックし、コード解析を行ってコード・ベース内のこれらの参照を見つけます。それらが根本的な原因である可能性が高いです。メモリを消費していることがわかります。これはリークの可能性があることを示しており、ソースコードをチェックする必要があります。(参照を破壊して検証する)コード内の疑わしいオブジェクトの参照を解除し、手順3から7を繰り返して、アプリケーションのメモリグラフが平坦になることを確認してください。あれば、根本的な原因が見つかったということです。チェックしてください。worship(プロファイラ崇拝)という考え方は止めておきたいと考えています。確かにプロファイラは素晴らしい助っ人ですが、それが全てではありません。プロファイラを使う主要な理由は整理された形でJVMの内部を公開するためです。場合、基本的な(無料の)プロファイラで十分に賄えます。メモリのトラブルシューティングの本当の課題は、プロファイラが公開している、問題の原因となっているアプリケーション・コードをどのようにして見つけるかということです。この問題を解決する唯一の方法は、アプリケーションのコードベースを理解し、Java言語を十分に理解することです。トラブルシューティング・ツールに精通し、一般的なトラブルシューティングの方法論を知っていれば、メモリ・リークの根本的な原因を見つけることはそれほど難しくないはずです。Apps”でその件について述べていきます。コメントをキャンセルコメントを入力してください。以下に詳細を記入するか、アイコンをクリックしてログインしてください。アカウントを使ってコメントしています。アカウントを使ってコメントしています。新しいコメントがついたらメールで通知。Inside現在40人フォロワーがいます。購読管理このバーを折りたたむ%d人のブロガーが「いいね」をつけました。