【Java仮想マシンの理解が深まる】JVM障害対応ツールの紹介

序文

JDK の bin ディレクトリに java.exe や javac.exe などのコマンド ライン ツールがあることは誰もが知っていますが、これらのツールは主に仮想マシンの実行状態の監視やトラブルシューティングに使用されます。これらのトラブルシューティング ツールは、オラクル社から単に「贈り物」として JDK ユーザーに提供されるものではありません. ソフトウェアの可用性と承認に応じて、次の 3 つのカテゴリに分類できます。


  • 商用認証ツール: 主に JMC (Java Mission Control) とそれが使用する JFR (Java Flight Recorder) JMC は、もともと JRockit からの運用および保守監視スイートであり、JDK 7 Update 40 以降、 OracleJDKに統合されています。別途ダウンロードする必要はありませんが、商用環境で使用するには料金がかかりました。

  • 正式にサポートされているツール: このタイプのツールは長期的にサポートされているツールです. プラットフォームや JDK のバージョンが異なると、このようなツールに若干の違いが生じる場合がありますが、特定のツールが突然なくなることはありません.

  • 実験的なツール: このタイプのツールは、「サポートされていない実験的な」(サポートされていない実験的な) 製品として説明書で宣言されており、将来的に正規になるか、特定の JDK バージョンでサイレントになる可能性があります。しかし実際には、それらは通常非常に安定しており、強力であり、アプリケーションのパフォーマンスの問題に対処し、障害を特定する上でも大きな役割を果たすことができます。

1. jps: 仮想マシン プロセス ステータス ツール

jps (JVM Process Status Tool) 関数: 実行中の仮想マシン プロセスを一覧表示し、仮想マシン実行のメイン クラス (メイン クラス、main() 関数が配置されているクラス) の名前とローカル仮想マシン固有の名前を表示できます。これらのプロセスの ID (LVMID)、ローカル仮想マシン識別子)。

コマンド形式:

jps [ options ] [ hostid ]

例:

jps
1764 RemoteMavenServer
18516 Launcher
17868 Jps

オプション:

オプション 説明
-q メインクラス情報を無視して、プロセスIDのみを出力する
-l メインクラスのフルネームを出力するか、JARパッケージ実行時のパスを出力する
-m 仮想マシン プロセスの開始時にメイン クラスの main() 関数に渡されるパラメータを出力します。
-の 仮想マシン プロセスの開始時に JVM パラメータを出力する

1. リモートマシン情報を出力する

jps は、RMI プロトコルを使用して、RMI サービスが有効になっているリモート仮想マシンのプロセス ステータスを照会することもできます. パラメータ hostid は、RMI レジストリに登録されているホスト名です.

jps リンクはリモートで JVM 情報を出力します。RMI を登録する必要があります。そうしないと、エラーが報告されます。

jps -lv 127.0.0.1
RMI Registry not available at 127.0.0.1:1099
Connection refused to host: 127.0.0.1; nested exception is:
        java.net.ConnectException: Connection refused: connect

1. RMI を登録し、jstatd を起動C:\Program Files\Java\jdk1.8.0_91\binする ディレクトリに jstatd.all.policy という名前のファイルを追加します。

jstatd.all.policy ファイルの内容は次のとおりです。

grant codebase "file:${java.home}/../lib/tools.jar" {
    
    
   permission java.security.AllPermission;
};

2. 構成ファイルを追加したら、追加した jstatd.all.policy ファイルを bin ディレクトリに登録します。

C:\Program Files\Java\jdk1.8.0_91\bin>jstatd -J-Djava.security.policy=jstatd.all.policy

成功例は次のとおりです。

C:\Users\Administrator>jps -lv 127.0.0.1
12708 sun.tools.jps.Jps -Denv.class.path=.;G:\Java\jdk1.8.0_91\lib\dt.jar;G:\Java\jdk1.8.0_91\lib\tools.jar; -Dapplication.home=C:\Program Files\Java\jdk1.8.0_91 -Xms8m
16116  exit -Xms128m -Xmx3096m -XX:ReservedCodeCacheSize=512m -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=100 -ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -XX:+HeapDumpOnOutOfMemoryError
 -Didea.vendor.name=JetBrains -Didea.paths.selector=IntelliJIdea2021.1 -XX:ErrorFile=C:\Users\Administrator\java_error_in_idea64_%p.log -XX:HeapDumpPath=C:\Users\Administrator\java_error_in_idea64.hprof
1764 org.jetbrains.idea.maven.server.RemoteMavenServer -Djava.awt.headless=true -Dmaven.defaultProjectBuilder.disableGlobalModelCache=true -Didea.version=2021.1.2 -Didea.maven.embedder.version=3.1.1 -Xmx768m -Dfile.e
18516 org.jetbrains.jps.cmdline.Launcher -Xmx700m -Djava.awt.headless=true -Djava.endorsed.dirs="" -Djdt.compiler.useSingleThread=true -Dpreload.project.path=G:/ideawork -Dpreload.config.path=G:/IntelliJ IDEA 2021.1.
net.preferIPv4Stack=true -Dio.netty.initialSeedUniquifier=1570513135976058670 -Dfile.encoding=GBK -Duser.language=zh -Duser.country=CN -Didea.paths.selector=IntelliJIdea2021.1 -Didea.home.path=G:\IntelliJ IDEA 2021.1
a2021.1/.IntelliJIdea/system/log/build-log -Djps.fallback.jdk.hom
2684 sun.tools.jstatd.Jstatd -Denv.class.path=.;G:\Java\jdk1.8.0_91\lib\dt.jar;G:\Java\jdk1.8.0_91\lib\tools.jar; -Dapplication.home=C:\Program Files\Java\jdk1.8.0_91 -Xms8m -Djava.security.policy=jstatd.all.policy

パラメータの組み合わせ:

jps -lm 127.0.0.1

2. jstat: 仮想マシン統計監視ツール

仮想マシンのさまざまな実行ステータス情報を監視するために使用される jstat (JVM 統計監視ツール)。ローカルまたはリモートの仮想マシン プロセスで、クラスの読み込み、メモリ、ガベージ コレクション、ジャストインタイム コンパイルなどのランタイム データを表示できます。

コマンド形式:

jstat [ option vmid [interval[s|ms] [count]] ]

vmid: リモート マシンを表示している場合は、次の形式に従う必要があります。[protocol:][//]lvmid[@hostname[:port]/servername]

interval と count は、クエリの間隔と回数を示します。たとえば、1000 ミリ秒ごとにプロセス ID の gc 収集ステータスをクエリし、毎回 5 回クエリを実行します。jstat -gc 111552 1000 3

オプションは主に、クラスのロード、ガベージ コレクション、ランタイム コンパイル ステータスの 3 つのカテゴリに分類されます。

オプション 説明
-クラス クラスのロード、アンロードの数、合計スペース、およびクラスのロードにかかる時間を監視します
-gc Eden 領域、2 つの Survivor 領域、old 世代、permanent 世代または jdk1.8 元の領域、容量、使用済み領域、総ガベージ コレクション時間などを含む Java ヒープの状況を監視します。
-g容量 監視内容は基本的に-gcと同じですが、主にJavaヒープの各領域が使用している最大・最小領域を中心に出力します
-gcutile 監視内容は基本的に -gc と同じですが、総容量に対する使用容量の割合を中心に出力します。
-gcause -gcutil と同じ機能ですが、最後のガベージ コレクションの原因を追加で出力します。
-gcnew 若い世代のガベージ コレクションを監視する
-gcnew容量 監視内容は基本的に -gcnew と同じで、出力は主に最大使用量と最小使用量を中心に
-gcold 古い世代のガベージ コレクションを監視する
-gcold容量 監視内容は基本的に -gcold と同じで、出力は主に最大使用量と最小使用量を中心に
-コンパイラ リアルタイムコンパイラでコンパイルされたメソッド、時間のかかる情報などを出力
-印刷コンパイル ジャストインタイム コンパイルされた出力メソッド
-gcperm容量 jdk1.7 以下、永続世代領域の統計
-gcmetacapacity jdk1.8、メタスペース統計

例:

C:\Users\Administrator>jstat -class 14944 1000 5
Loaded  Bytes  Unloaded  Bytes     Time
  6216 11190.6        1     0.9       4.70
  6216 11190.6        1     0.9       4.70
  6216 11190.6        1     0.9       4.70

C:\Users\Administrator>jstat -compiler 14944 1000 5
Compiled Failed Invalid   Time   FailedType FailedMethod
    3290      0       0     7.73          0
    3290      0       0     7.73          0
C:\Users\Administrator>jstat -gcutil 14944 1000 5
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00  34.71  89.33   6.49  94.64  91.92      5    0.080     1    0.048    0.128
  0.00  34.71  89.33   6.49  94.64  91.92      5    0.080     1    0.048    0.128


C:\Users\Administrator>jstat -gc 14944 1000 5
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC
6656.0 10752.0  0.0   3732.1 131072.0 117082.2  82944.0     5384.1   28416.0 26893.9 3840.0 3529.8      5    0.080   1

3. jinfo: Java構成情報ツール

jinfo (Java の構成情報) の機能は、仮想マシンのさまざまなパラメーターをリアルタイムで表示および調整することです。

コマンド形式:

jinfo [ option ] pid

例:

C:\Users\Administrator>jinfo -flag MetaspaceSize 14944
-XX:MetaspaceSize=21807104

4. jmap: Java メモリ マッピング ツール

jmap (Memory Map for Java) コマンドは、ヒープ ダンプ スナップショット (一般に heapdump またはダンプ ファイルと呼ばれます) を生成するために使用されます。jmap コマンドを使用しない場合でも、Java ヒープ ダンプ スナップショットを取得するための「暴力的な」手段がいくつかあります。オーバーフロー例外が発生した場合、-XX: +HeapDumpOnCtrlBreak パラメーターを介して、[Ctrl]+[Break] キーを使用して、仮想マシンにヒープ ダンプ スナップショット ファイルを生成させるか、Kill-3 コマンドを介してプロセス終了シグナルを送信できます。 Linux システムが仮想マシンを「怖がらせる」ために、ヒープ ダンプのスナップショットも正常に取得できます。

jmap の役割は、ヒープダンプのスナップショットを取得するだけでなく、ファイナライズ実行キュー、Java ヒープ、およびメソッド領域の詳細な情報 (スペースの使用状況、現在どのコレクターが使用されているかなど) を照会することです。

コマンド形式:

jmap [ option ] pid

オプション: オプション パラメータ

pid: 構成情報を出力する必要があるプロセスの ID

実行可能ファイル: コア ダンプを生成する Java 実行可能ファイル

core: 構成情報を出力する必要があるコア ファイル

server-id: オプションの一意の ID。複数のデバッグ サーバーが同じリモート ホストで実行されている場合は、このオプション パラメーターを使用してサーバーを識別します。

リモート サーバーの IP またはホスト名: リモート デバッグ サーバーの IP アドレスまたはホスト名

オプション:

オプション 説明
-投げ捨てる Java ヒープ ダンプ スナップショットを生成します。
-ファイナライザー情報 Finalizer スレッドが F-Queue で finalize メソッドを実行するのを待っているオブジェクトを表示します。Linux プラットフォーム
-ヒープ 使用されているコレクター、パラメーター構成、世代状況など、Java ヒープに関する詳細情報を表示します。Linux プラットフォーム
-ヒスト クラス、インスタンス数、合計容量など、ヒープ内のオブジェクト統計を表示します
-permstat 永続世代のメモリ ステータスを表示する、jdk1.7、永続世代
-F 仮想マシン プロセスが -dump オプションに応答しない場合、スナップショットを強制できます。Linux プラットフォーム

ヒープ ダンプ ファイルの例:

jmap -dump:live,format=b,file=heap.bin 14944
C:\Users\Administrator>jmap -dump:format=b,file=idea.bin 14944
Dumping heap to C:\Users\Administrator\idea.bin ...
Heap dump file created

印刷ロード クラスの例:

C:\Users\Administrator>jmap -clstats 14944
Attaching to process ID 14944, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.91-b15
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing liveness.......liveness analysis may be inaccurate ...
class_loader    classes bytes   parent_loader   alive?  type

<bootstrap>     1698    2983149   null          live    <internal>
0x00000007736a41e8      1       880     0x00000006c1c14038      dead    sun/reflect/DelegatingClassL

5. jhat: 仮想マシンのヒープ ダンプ スナップショット分析ツール

JDK は、jmap で生成されたヒープ ダンプ スナップショットを分析するために jmap で使用される jhat (JVM ヒープ分析ツール) コマンドを提供します。jhat には小さな HTTP/Web サーバーが組み込まれており、ヒープ ダンプのスナップショットの分析結果を生成した後、ブラウザーで表示できます。

ただし、実際の作業では、他に使用できるツールがまったくない場合を除き、ほとんどの人は jhat コマンドを直接使用してヒープ ダンプ スナップショット ファイルを分析することはありません。主な理由は 2 つあります。

  • 1つは、アプリケーションがデプロイされているサーバーでヒープ・ダンプ・スナップショットを直接分析することは通常行われないことです. 分析が機能するため、分析が可能な場合でも、可能な限りヒープ・ダンプ・スナップショット・ファイルを他のマシンにコピーして分析します.ハードウェア リソースを消費するプロセスは別のマシンで実行する必要があるため、コマンド ライン ツールによって制限される必要はありません。

  • また、jhat の解析機能が比較的シンプルであることも理由の 1 つで、後で紹介する VisualVM や、ヒープ ダンプのスナップショット ファイルを解析するために専門的に使用されている Eclipse Memory Analyzer や IBM HeapAnalyzer などのツールは、jhat よりも強力な場合があります。プロの分析機能。次のコード リストは、jhat を使用して、前のセクションで jmap によって生成された Eclipse IDE のメモリ スナップショット ファイルを分析する方法を示しています。

例:

C:\Users\Administrator>jhat idea.bin
Reading from idea.bin...
Dump file created Wed Oct 26 20:48:34 CST 2022
Snapshot read, resolving...
Resolving 1394404 objects...
Chasing references, expect 278 dots...................................................................................
Eliminating duplicate references......................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

「Server is ready.」というプロンプトが画面に表示された後、ユーザーはブラウザーに http://localhost:7000/ と入力して、図に示すように分析結果を表示できます。
ここに画像の説明を挿入ここに画像の説明を挿入

デフォルトでは解析結果はパッケージ単位でグループ化されて表示されます. メモリリークの解析は主に「ヒープヒストグラム」(jmap-histo関数と同じ)とOQLタブの関数を使用します. 前者はオブジェクトを見つけることができます.メモリ内の最大総容量。後者は、SQL に似た構文を使用してメモリ内のオブジェクトのクエリとカウントを行う標準的なオブジェクト クエリ言語です。

六、jstack: Java スタック トレース ツール

jstack (Java のスタック トレース) コマンドを使用して、現時点での仮想マシンのスレッド スナップショット (一般にスレッド ダンプまたは javacore ファイルと呼ばれます) を生成します。スレッド スナップショットは、現在の仮想マシンの各スレッドによって実行されているメソッド スタックのコレクションです. スレッド スナップショットを生成する目的は、通常、スレッド間のデッドロック、無限のスレッドなど、スレッドの長い一時停止の原因を突き止めることです.ループ、または外部リソースの要求によって引き起こされる長時間 ハングなどは、長時間のスレッド一時停止の一般的な原因です。スレッドが一時停止したときに、jstack を介して各スレッドのコール スタックを確認すると、応答していないスレッドがバックグラウンドで何をしているのか、またはどのリソースを待機しているのかを知ることができます。

コマンド形式:

jstack [ option ] vmid

オプション:

オプション 説明
-F 通常出力の要求が無応答の場合、強制出力スレッドスタック
-l スタックに加えて、ロックに関する追加情報を表示します
-m ネイティブメソッドが呼び出された場合、c/c++ スタックを表示できます

例:

jstack -l 14944

JDK 5 以降では、java.lang.Thread クラスに getAllStackTraces() メソッドが追加され、仮想マシン内のすべてのスレッドの StackTraceElement オブジェクトが取得されます。このメソッドを使用すると、jstack のほとんどの機能を数行の簡単なコードで完了することができます. 実際のプロジェクトでは、このメソッドを呼び出して管理者ページを作成することができます. ブラウザを使用していつでもスレッド スタックを表示できます.次のコード リストに示すとおりです。

<%@ page import="java.util.Map"%>
<html>
<head>
<title>服务器线程信息</title>
</head>
<body>
<pre>
<%
	for (Map.Entry<Thread, StackTraceElement[]> stackTrace : Thread.getAllStack-Traces().entrySet()) {
    
    
		Thread thread = (Thread) stackTrace.getKey();
		StackTraceElement[] stack = (StackTraceElement[]) stackTrace.getValue();
		if (thread.equals(Thread.currentThread())) {
    
    
		continue;
		}
		out.print("\n线程: " + thread.getName() + "\n");
		for (StackTraceElement element : stack) {
    
    
		out.print("\t"+element+"\n");
		}
	}
%>
</pre>
</body>
</html>

7. 基本ツールのまとめ

次の表に、JDK に付属するすべてのツール (以前は存在していたが最新バージョンで削除されたものを含む) とその簡単な用途を示します。JDK の上位バージョンでは、これらのツールのほとんどに、より強力な代替ツールがあります。例えば、JCMDとJHSDBのコマンドラインモードですが、使い方は似ています.JDKのどのバージョンが開発されたとしても、これらの基本的なツールコマンドを学ぶことは時代遅れで無駄ではありません.

  • 基本ツール: 基本的なプログラムの作成と操作をサポートするために使用されます。

    ここに画像の説明を挿入

  • セキュリティ: プログラムの署名、セキュリティ テストの設定などに使用されます。
    ここに画像の説明を挿入

  • 国際化: ローカル言語ファイルの作成に使用されます。

    ここに画像の説明を挿入

  • リモート メソッド呼び出し: Web またはネットワークを介したサービスの対話用。
    ここに画像の説明を挿入

Java IDL および RMI-IIOP: JDK 11 で 10 年以上の CORBA サポートが終了したため、これらのツールは提供されなくなりました。
ここに画像の説明を挿入

  • 展開ツール: プログラムのパッケージ化、公開、および展開に使用されます。
    ここに画像の説明を挿入

  • Java Web Start。
    ここに画像の説明を挿入

  • パフォーマンスの監視とトラブルシューティング: Java 仮想マシンの実行情報の監視と分析、および問題のトラブルシューティングに使用されます。
    ここに画像の説明を挿入

  • WebService ツール: CORBA とともに JDK 11 で削除されました。
    ここに画像の説明を挿入

  • REPL およびスクリプト ツール。
    ここに画像の説明を挿入

ここに画像の説明を挿入
いいね、集め
てフォロー

おすすめ

転載: blog.csdn.net/qq_35764295/article/details/127538540