プロセスのヒープダンプを取得するには、jmap
を実行する必要がありました。しかしjvm
は戻りました:
Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
そこで、-F
を使用しました。
./jmap -F -dump:format=b,file=heap.bin 10330
Attaching to process ID 10331, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.51-b03
Dumping heap to heap.bin ...
-F
を使用すると、ヒープダンプを取得しても問題ありませんか?jmap
とjmap -F
、およびjstack
とjstack -F
は、まったく異なるメカニズムを使用してターゲットJVMと通信します。
-F
なしで実行すると、これらのツールは ダイナミックアタッチメカニズム を使用します。これは次のように機能します。
Javaプロセス1234に接続する前に、jmap
は、ターゲットプロセスの作業ディレクトリまたは.attach_pid1234
にファイル/tmp
を作成します。
次に、jmap
はSIGQUIT
をターゲットプロセスに送信します。 JVMがシグナルをキャッチして.attach_pid1234
を見つけると、AttachListener
スレッドを開始します。
AttachListener
スレッドは、外部ツールからのコマンドをリッスンするUNIXドメインソケット/tmp/.Java_pid1234
を作成します。
(jmap
からの)接続が受け入れられるセキュリティ上の理由から、JVMはソケットピアの資格情報がJVMプロセスのeuid
およびegid
と等しいことを確認します。そのため、jmap
は、別のユーザー(rootでも)で実行すると機能しません。
jmap
はソケットに接続し、dumpheap
コマンドを送信します。
このコマンドは、JVMのAttachListener
スレッドによって読み取られて実行されます。すべての出力はソケットに送り返されます。ヒープダンプはJVMによってインプロセスで直接作成されるため、操作は非常に高速です。ただし、JVMは safepoints でのみこれを行うことができます。セーフポイントに到達できない場合(プロセスがハングする、応答しない、または長いGCが進行中)、jmap
はタイムアウトして失敗します。
Dynamic Attachの利点と欠点をまとめましょう。
長所
jmap
またはjstack
の任意のバージョンを使用して、JVMの他のバージョンに接続できます。短所
euid
/egid
)で実行する必要があります。-XX:+DisableAttachMechanism
で起動されている場合は機能しません。-F
を指定して実行すると、ツールは HotSpot Serviceability Agent を備えた特別なモードに切り替わります。このモードでは、ターゲットプロセスがフリーズします。ツールは、OSデバッグ機能、つまりLinuxでは ptrace
を介してメモリを読み取ります。
jmap -F
は、ターゲットJVMでPTRACE_ATTACH
を呼び出します。 SIGSTOP
シグナルに応じて、ターゲットプロセスは無条件に中断されます。
ツールは、PTRACE_PEEKDATA
を使用してJVMメモリを読み取ります。 ptrace
は一度に1つのWordしか読み取ることができないため、ターゲットプロセスの大きなヒープを読み取るには呼び出しが多すぎます。これは非常に遅いです。
このツールは、特定のJVMバージョンの知識に基づいてJVM内部構造を再構築します。 JVMのバージョンごとにメモリレイアウトが異なるため、-F
モードは、jmap
がターゲットJavaプロセスと同じJDKからのものである場合にのみ機能します。
ツールは、ヒープダンプ自体を作成し、ターゲットプロセスを再開します。
長所
ptrace
は、OSレベルの特権で十分な場合に機能します。例えば。 root
は、他のすべてのユーザーのプロセスをダンプできます。短所
jmap
はすべての特殊なケースを処理しようとしますが、ターゲットJVMが一貫性のない状態になる場合があります。注
強制モードでヒープダンプを取得するより高速な方法があります。最初に、 gcore
でコアダンプを作成してから、生成されたコアファイルに対してjmap
を実行します。 関連する質問 を参照してください。
私は、jmap(およびそれを使用してヒープダンプを生成する場合はおそらくjvisualvm)が、jmapを実行しているユーザーが、ダンプしようとしているプロセスを実行しているのと同じユーザーでなければならないことを強制することを発見しました。
私の場合、ヒープダンプが必要なjvmは、Linuxユーザー「jboss」によって実行されています。 Sudo jmap -dump:file.bin <pid>
が「ソケットを開くことができません:」を報告していた場合、次を使用してヒープダンプを取得できました。
Sudo -u jboss jmap -dump:file.bin <pid>
ben_wing が言ったように、次のコマンドで実行できます:
Sudo -u jboss-as jmap -dump:file.bin <pid>
(私の場合、ユーザーはjboss-as
ですが、あなたはjboss
または他のユーザーでもかまいません。)
ただし、パスワードの入力を求められたため([Sudo] password for ec2-user:
)、パスワードの入力を求めずにSudo
を実行できたため、十分ではありませんでした他のコマンドで。
私は解決策を見つけました here 、そして私は最初に別のSudo
を追加する必要がありました:
Sudo sudo -u jboss-as jmap -dump:file.bin <pid>
jcmd
やjinfo
などの他のコマンドでも動作します。