JVMのガベージコレクション機能により、コードベースにメモリリークが発生する機会は大幅に減少します。しかし、ガベージコレクションではメモリリークが完全に除去されないため、AppDynamics にはサポートされる JVM の自動リーク検知機能が含まれています。

権限

自動リーク検知を有効化するには、エージェントプロパティの構成権限が必要です。

オンデマンド キャプチャ セッションを開始するには、Advanced Agent Operation 権限が必要です。

AppDynamics ロールベースのアクセス制御の詳細については、「ロールと権限」を参照してください。

自動リーク検知の概要

自動リーク検知は、[Node] ダッシュボードの [Memory] タブで利用できます。自動リーク検知は JVM のオーバーヘッドを増大させるため、デフォルトでは無効になっています。メモリリークの問題が疑われる場合にのみリーク検知モードを有効化してください。リークの原因が特定されたら自動リーク検知を無効化してください。

自動リーク検知は、オンデマンドキャプチャセッションを使用して、キャプチャ期間内に積極的に使用されるコレクション(JDK MapまたはCollectionインターフェースを実装するクラス)をキャプチャします。デフォルトのキャプチャ期間は10分です。

AppDynamicsは、以下の基準を満たすすべてのJavaコレクションを追跡します。

  • コレクションが少なくとも 30 分間有効となる。
  • コレクションに少なくとも 1000 個のエレメントがある。 
  • コレクションのディープサイズは少なくとも5 MB。エージェントは、コレクションのすべてのオブジェクトについて再帰的にオブジェクトグラフを横断し、ディープサイズを計算する。

リーク検知基準のデフォルトは、以下のノードプロパティで定義されます。

  • minimum-age-for-evaluation-in-minutes

  • minimum-number-of-elements-in-collection-to-deep-size

  • minimum-size-for-evaluation-in-mb

詳細については、「アプリケーションエージェントのノードプロパティ」を参照してください。 

Javaエージェントはコレクションを追跡し、線形回帰モデルを使ってリークの可能性を識別します。一定期間のコレクションへの頻繁なアクセスを追跡することで、リークの根本原因を特定できます。

コレクションが基準を満たすと、AppDynamicsはコレクションのサイズの長期的な成長傾向をモニターリングします。プラスの成長は、コレクションがメモリリークの元である可能性を示しています。

AppDynamicsがリーク元コレクションを特定すると、Javaエージェントは30分ごとに自動的に診断をトリガーします。診断では、コードパスのシャローコンテンツダンプとアクティビティトレース、およびコレクションにアクセスするビジネストランザクションがキャプチャされます。エージェントによってモニタリングされるリーク元コレクションをドリルダウンすることで、コンテンツサマリキャプチャセッションとアクセストラッキングセッションを手動でトリガーできます。

また、カスタムメモリ構造のメモリリークをモニタリングすることもできます。通常、カスタムメモリ構造はキャッシングソリューションとして使用されます。分散環境では、キャッシングがメモリリークの主な原因になりやすい傾向があります。そのため、こうしたメモリ構造のメモリ統計を管理および追跡することが重要です。それには、事前にカスタムメモリ構造を構成する必要があります。詳細については、「Javaのカスタムメモリ構造」を参照してください。

メモリリークのトラブルシューティングのワークフロー

以下のワークフローを使用して、メモリリークの問題の可能性があると識別されたJVMでメモリリークのトラブルシューティングを行います。

  1. JVM メモリリークの可能性があるメモリをモニターリングする
  2. 自動リーク検知を有効化する
  3. オンデマンドキャプチャセッションを開始する
  4. リークの状態の検出とトラブルシューティング

これらの手順について、以降のセクションで説明します。 

JVMリークの可能性があるメモリのモニタリング

ノードダッシュボードを使用してメモリリークを特定します。メモリリークの可能性は、ヒープの増加傾向とOld/Tenured世代のメモリプールからわかります。

急激に増加に傾いている場合、オブジェクトは自動的にリークの可能性があるオブジェクトとしてマークされます。

自動メモリリークのダッシュボードには、以下のものが表示されます。

  • Collection Size:コレクションのエレメントの数。
  • Potentially Leaking:リークの可能性があるコレクションは赤でマークされる。リークの可能性があるオブジェクトに対して診断セッションを開始する必要がある。
  • Status:診断セッションがオブジェクトで開始された場合に示される。
  • Collection Size Trend:急激なプラス成長はメモリリークの可能性を示す。

(info)Tip: 長期のコレクションを特定するには、JVMの開始時間とオブジェクト作成時間を比較する。

キャプチャされたコレクションが表示されない場合は、潜在的なメモリリークを検出するための構成が正しいことを確認してください。

メモリリーク検知の有効化

自動リーク検知機能によって、メモリリーク検出を行うことができます。自動リーク検知機能が有効化され、キャプチャセッションが開始されると、AppDynamicsは頻繁に使用されるコレクションをすべて追跡します。そのため、このモードを使用するとオーバーヘッドが大きくなります。

メモリリークの問題が特定されたときにのみ自動リーク検知モードを有効化し、[Start On Demand Capture Session] をクリックして頻繁に使用されるコレクションのモニターリングを開始し、リーク元コレクションを検出します。

リークを特定し、解決したら、キャプチャセッションとリーク検知モードをオフにします。

最適なパフォーマンスを実現するには、一回につきひとつのコレクションを診断します。

メモリリークのトラブルシューティング

メモリリークの可能性が検出されたら、リークのトラブルシューティングとして以下の3つのアクションを実行します。

モニタリングするコレクションオブジェクトの選択

自動リーク検知ダッシュボードで、クラス名を右クリックし、[Drill Down] をクリックします。

パフォーマンス上の理由から、一度にひとつのコレクションオブジェクトでトラブルシューティング セッションを開始します。

コンテンツ検査の使用

コンテンツ検査は、トラブルシューティングを開始できるように、コレクションがアプリケーションのどの部分に属するかを特定します。特定のコレクションの要素すべてのヒストグラムをモニタリングできます。

オンデマンドキャプチャセッションを開始して自動リーク検知を有効化し、トラブルシューティングを行うオブジェクトを選択して以下の手順を行います。

  1. [Content Inspection] タブをクリックします。
  2. [Start Content Summary Capture Session] をクリックし、コンテンツ検査セッションを開始する。
  3. セッション期間を入力。データ生成に少なくとも1〜2分を割り当てる。
  4. [Refresh] をクリックし、セッションデータを取得する。
  5. スナップショットをクリックし、各セッションの詳細を表示する。

アクセストラッキングの使用

アクセストラッキングを使用して、コレクションオブジェクトにアクセスする実際のコードパスとビジネストランザクションを表示します。

上記の「Workflow to Troubleshoot Memory Leaks」にあるといて、自動リーク検知を有効化し、オンデマンド キャプチャ セッションを開始し、トラブルシューティングを行うオブジェクトを選択して以下の手順を行います。

  1. [Access Tracking] タブを選択。
  2. [Start Access Tracking Session] をクリックし、トラッキングセッションを開始する。
  3. セッション期間を入力。データ生成に少なくとも1-2分を割り当てる。
  4. [Refresh] をクリックし、セッションデータを取得する。
  5. スナップショットをクリックし、各セッションの詳細を表示する。

トラブルシューティング情報ペインには、セッションに関連するJavaスタックトレースが表示されます。デフォルトで、スタックトレースは10行目までの深さで表示されます。一時的にキャプチャされる行数を増やしたい場合は、「アプリケーションエージェントのノードプロパティ参照資料」に記載されている maximum-activity-trace-stack-depth Java エージェントプロパティを使用します。

スタックトレースの深さを増やすと、システムリソースを大きく消費します。希望の情報をキャプチャした後は、そのプロパティを削除するか、デフォルト値を 10 に戻してください。