多くのJVMメモリ構造とオブジェクト作成について説明しました。これらはJVMの基本ですが、最終的な目標はそれを調整できるようにすることです。アプリケーションが応答せず、OOM、メモリリーク、または死を報告することがあります。解決するにはこれらの問題には、jdkに付属するいくつかのコマンドラインツールを学ぶことが不可欠です。これらのツールの基盤により、問題が発生したときに問題を解決するために再起動するだけでなく、アプリケーションの問題を解決するから始めることができます。根本的な原因により、Java開発の内部能力が向上します
一般的に、一般的に使用されるjdkツールは次のとおりです。
- jps:すべてのJavaプロセスを表示
- jstat:仮想マシンのさまざまな動作ステータス情報を監視します
- jinfo:仮想マシンのさまざまなパラメータをリアルタイムで表示および調整します
- jmap:ヒープストレージスナップショットを生成する
- jhat:ヒープダンプファイルを分析します
- jstack:現時点での仮想マシンのスレッドスナップショットを生成します
1つは、JDKにはツールが付属しています
jps
:すべてのJavaプロセスを表示
jps
(JVMプロセスステータス)コマンドUNIXライクなps
コマンド。
jps
:仮想マシン実行のメインクラスの名前と、これらのプロセスの一意のID(ローカル仮想マシン識別子、LVMID)を表示します。
jps -q
:プロセスのローカル仮想マシンの一意のIDのみを出力します。
jps -l
:メインクラスのフルネームを出力します。プロセスがJarパッケージを実行している場合は、Jarパスを出力します。
jps -v
:仮想マシンプロセスの開始時にJVMパラメータを出力します。
jps -m
:Javaプロセスのmain()関数に渡されたパラメータを出力します。
jstat
:仮想マシンのさまざまな動作ステータス情報を監視します
jstat(JVM統計監視ツール)は、仮想マシンのさまざまな動作ステータス情報を監視するために使用されるコマンドラインツールです。クラス情報、メモリ、ガベージコレクション、JITコンパイル、およびその他の実行中のデータを仮想マシンプロセスでローカルまたはリモートで表示できます(リモートホストからのRMIサポートが必要です)。GUIがなく、プレーンテキストのみを提供するサーバー上。コンソール環境、それは操作中に仮想マシンのパフォーマンスの問題を見つけるための選択のツールになります。
jstat
コマンド形式:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
たとえば、jstat -gc -h3 31736 1000 10
ID 31736 gcの場合の分析プロセスを示します。レコードは、1000msごとに1回、印刷を停止するために10回印刷され、3行ごとにインジケータヘッドが印刷されます。
一般的なオプションは次のとおりです。
jstat -class vmid
:ClassLoaderの関連情報を表示します。jstat -compiler vmid
:JITコンパイルの関連情報を表示します。jstat -gc vmid
:GCに関連するヒープ情報を表示します。jstat -gccapacity vmid
:各世代の容量と使用量を表示します。jstat -gcnew vmid
:新世代の情報を表示します。jstat -gcnewcapcacity vmid
:新世代のサイズと使用法を表示します。jstat -gcold vmid
:旧世代と永続世代の動作統計を表示します。jdk1.8以降、永続世代が削除されたため、このオプションは旧世代のみを示します。jstat -gcoldcapacity vmid
:老後のサイズを表示します。jstat -gcpermcapacity vmid
:永続世代のサイズを表示します。jdk1.8以降、永続世代が削除されたため、このオプションは存在しなくなりました。jstat -gcutil vmid
:ガベージコレクション情報を表示します。
さらに、-t
リストされたパラメータをタイムスタンプに追加すると、プログラムの実行時間を表示するための情報が出力されます。
jinfo
:仮想マシンのさまざまなパラメータをリアルタイムで表示および調整します
jinfo vmid
:現在のJVMプロセスのすべてのパラメーターとシステム属性を出力します(最初の部分はシステム属性で、2番目の部分はJVMパラメーターです)。
jinfo -flag name vmid
:名前に対応するパラメータの特定の値を出力します。たとえば、MaxHeapSizeを出力し、現在のjvmプロセスがGCログの印刷を有効にしているかどうかを確認します(-XX:PrintGCDetails
:詳細なGCログモード。どちらもデフォルトでは無効になっています)。
C:\Users\SnailClimb>jinfo -flag MaxHeapSize 17340
-XX:MaxHeapSize=2124414976
C:\Users\SnailClimb>jinfo -flag PrintGC 17340
-XX:-PrintGC
jinfoを使用すると、仮想マシンを再起動せずにjvmのパラメーターを動的に変更できます。特にオンライン環境は特に便利です。次の例を参照してください。
jinfo -flag [+|-]name vmid
対応する名前のパラメータをオンまたはオフにします。
C:\Users\SnailClimb>jinfo -flag PrintGC 17340
-XX:-PrintGC
C:\Users\SnailClimb>jinfo -flag +PrintGC 17340
C:\Users\SnailClimb>jinfo -flag PrintGC 17340
-XX:+PrintGC
jmap
:ヒープダンプスナップショットを生成する
jmap
(Memory Map for Java)コマンドは、ヒープダンプスナップショットを生成するために使用されます。jmap
コマンドを使用しない場合は、Javaヒープダンプを取得するために“-XX:+HeapDumpOnOutOfMemoryError”
パラメーターを使用して、OOM例外が発生した後に仮想マシンがダンプファイルを自動的に生成できるようにします。Linuxコマンドkill -3
はプロセスを終了して、ダンプを取得するための信号を送信できます。ファイル。
jmap
の役割は、ダンプファイルを取得することだけでなく、ファイナライザー実行キュー、Javaヒープ、および現在使用されているコレクターなどのスペース使用量などの永続的な生成の詳細情報を照会することもできます。またjinfo
、jmap
Windowsプラットフォームには多くの機能があるため、制限もあります。
例:指定したアプリケーションのヒープスナップショットをデスクトップに出力します。後で、jhatやVisualVMなどのツールを使用してヒープファイルを分析できます。
C:\Users\SnailClimb>jmap -dump:format=b,file=C:\Users\SnailClimb\Desktop\heap.hprof 17340
Dumping heap to C:\Users\SnailClimb\Desktop\heap.hprof ...
Heap dump file created
jhat
:ヒープダンプファイルを分析します
jhat
ヒープダンプファイルの分析に使用され、ユーザーがブラウザで分析結果を表示できるようにHTTP / HTMLサーバーを確立します。
C:\Users\SnailClimb>jhat C:\Users\SnailClimb\Desktop\heap.hprof
Reading from C:\Users\SnailClimb\Desktop\heap.hprof...
Dump file created Sat May 04 12:30:31 CST 2019
Snapshot read, resolving...
Resolving 131419 objects...
Chasing references, expect 26 dots..........................
Eliminating duplicate references..........................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
http:// localhost:7000 /にアクセスします
jstack
:現時点での仮想マシンのスレッドスナップショットを生成します
jstack
(Stack Trace for Java)コマンドは、現時点での仮想マシンのスレッドスナップショットを生成するために使用されます。スレッドスナップショットは、現在の仮想マシンの各スレッドによって実行されているメソッドスタックのコレクションです。
スレッドスナップショットを生成する目的は、主に、スレッド間のデッドロック、無限ループ、外部リソースの要求によって引き起こされる長い待機など、スレッドが長時間ストールする原因を特定することです。これらはすべて、スレッドがストールする理由です。長い間。スレッドが停止した場合、jstack
各スレッドの呼び出しスタックを調べることで、応答しないスレッドがバックグラウンドで何を行っているか、またはスレッドが待機しているリソースを知ることができます。
以下は、スレッドデッドロックのコードです。ここではjstack
、デッドロック、デッドロック出力情報を確認し、スレッドのデッドロックを見つけるコマンドを渡します。
public class DeadLockDemo {
private static Object resource1 = new Object();//资源 1
private static Object resource2 = new Object();//资源 2
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "线程 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "线程 2").start();
}
}
出力
Thread[线程 1,5,main]get resource1
Thread[线程 2,5,main]get resource2
Thread[线程 1,5,main]waiting get resource2
Thread[线程 2,5,main]waiting get resource1
スレッドAは、同期(resource1)を介してresource1のモニターロックを取得し、Thread.sleep(1000);
スレッドBを実行できるようにするためにスレッドAを1秒間スリープしてから、resource2のモニターロックを取得します。スレッドAとスレッドBはどちらも、スリープが終了した後、相互にリソースを要求し始めます。その後、2つのスレッドは相互に待機状態になり、デッドロックも発生します。
することによりjstack
、コマンド解析:
C:\Users\SnailClimb>jps
13792 KotlinCompileDaemon
7360 NettyClient2
17396
7972 Launcher
8932 Launcher
9256 DeadLockDemo
10764 Jps
17340 NettyServer
C:\Users\SnailClimb>jstack 9256
出力の一部は次のとおりです。
Found one Java-level deadlock:
=============================
"线程 2":
waiting to lock monitor 0x000000000333e668 (object 0x00000000d5efe1c0, a java.lang.Object),
which is held by "线程 1"
"线程 1":
waiting to lock monitor 0x000000000333be88 (object 0x00000000d5efe1d0, a java.lang.Object),
which is held by "线程 2"
Java stack information for the threads listed above:
===================================================
"线程 2":
at DeadLockDemo.lambda$main$1(DeadLockDemo.java:31)
- waiting to lock <0x00000000d5efe1c0> (a java.lang.Object)
- locked <0x00000000d5efe1d0> (a java.lang.Object)
at DeadLockDemo$$Lambda$2/1078694789.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"线程 1":
at DeadLockDemo.lambda$main$0(DeadLockDemo.java:16)
- waiting to lock <0x00000000d5efe1d0> (a java.lang.Object)
- locked <0x00000000d5efe1c0> (a java.lang.Object)
at DeadLockDemo$$Lambda$1/1324119927.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
このjstack
コマンドが詳細スレッドのデッドロックを取得するのに役立っていることがわかります。