jmapを実行してソケットファイルを開くことができません


88

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 ...
  1. -F ヒープダンプを取るのに使用しても大丈夫ですか?
  2. 私は20分待っていますが、まだ終わっていません。なぜ何かアイデアはありますか?

回答:


187

jmapjmap -F、およびjstackjstack -Fは、ターゲットJVMと通信するために完全に異なるメカニズムを使用します。

jmap / jstack

-Fこれらのツールなしで実行する場合は、動的アタッチメカニズムを使用してください。これは次のように機能します。

  1. Javaプロセス1234に接続する前に、ターゲットプロセスの作業ディレクトリまたはにjmapファイル.attach_pid1234を作成します/tmp

  2. 次に、ターゲットプロセスにjmap送信SIGQUITします。JVMがシグナルをキャッチして見つけると.attach_pid1234AttachListenerスレッドを開始します。

  3. AttachListenerスレッドは/tmp/.java_pid1234、外部ツールからのコマンドをリッスンするUNIXドメインソケットを作成します。

  4. (からのjmap)接続が受け入れられるときのセキュリティ上の理由から、JVMは、ソケットピアの資格情報がJVMプロセスの資格情報と等しいことeuidを確認しますegid。そのためjmap、別のユーザーが実行した場合(rootでも)、機能しません。

  5. jmapソケットに接続し、dumpheapコマンドを送信します。

  6. このコマンドはAttachListener、JVMのスレッドによって読み取られて実行されます。すべての出力はソケットに送り返されます。ヒープダンプはJVMによって直接インプロセスで作成されるため、操作は非常に高速です。ただし、JVMはセーフポイントでのみこれを実行できます。セーフポイントに到達できない場合(たとえば、プロセスがハングしている、応答していない、または長いGCが進行中の場合)、jmapタイムアウトして失敗します。

DynamicAttachの長所と短所を要約してみましょう。

長所。

  • ヒープダンプおよびその他の操作は、JVMによって最大速度で共同で実行されます。
  • jmapまたはの任意のバージョンを使用してjstack、JVMの他のバージョンに接続できます。

短所

  • ツールは、ターゲットJVMと同じユーザー(euid/ egid)で実行する必要があります。
  • ライブで正常なJVMでのみ使用できます。
  • ターゲットJVMがで開始されている場合は機能しません-XX:+DisableAttachMechanism

jmap -F / jstack -F

-Fツールを使用して実行すると、HotSpot ServiceabilityAgentを備えた特別モードに切り替わります。このモードでは、ターゲットプロセスは凍結されます。ツールは、OSデバッグ機能、つまりptraceLinuxを介してメモリを読み取ります。

  1. jmap -FPTRACE_ATTACHターゲットJVMで呼び出します。ターゲットプロセスは、SIGSTOPシグナルに応答して無条件に中断されます。

  2. このツールは、を使用してJVMメモリを読み取りますPTRACE_PEEKDATAptrace一度に読み取ることができるのは1ワードのみであるため、ターゲットプロセスの大きなヒープを読み取るために必要な呼び出しが多すぎます。これは非常に遅いです。

  3. このツールは、特定のJVMバージョンの知識に基づいてJVM内部構造を再構築します。JVMのバージョンが異なればメモリレイアウトも異なるため、-FモードjmapはターゲットJavaプロセスと同じJDKからのものである場合にのみ機能します。

  4. このツールは、ヒープダンプ自体を作成してから、ターゲットプロセスを再開します。

長所。

  • ターゲットJVMからの協力は必要ありません。ハングしたプロセスでも使用できます。
  • ptraceOSレベルの権限で十分な場合はいつでも機能します。たとえばroot、他のすべてのユーザーのプロセスをダンプできます。

短所

  • 大きなヒープの場合は非常に遅くなります。
  • ツールとターゲットプロセスは、同じバージョンのJDKのものである必要があります。
  • ツールが強制モードで取り付けられている場合、セーフポイントは保証されません。jmapすべての特殊なケースを処理しようとしますが、ターゲットJVMが一貫した状態にない場合があります。

注意

強制モードでヒープダンプを取得するより高速な方法があります。まず、でコアダンプを作成してから、生成されたコアファイルをgcore実行jmapします。関連する質問を参照してください。


85

jmap(およびヒープダンプを生成するために使用する場合はおそらくjvisualvm)により、jmapを実行しているユーザーは、ダンプしようとしているプロセスを実行しているユーザーと同じである必要があることがわかりました。

私の場合、ヒープダンプが必要なjvmは、Linuxユーザー「jboss」によって実行されています。sudo jmap -dump:file.bin <pid>「ソケットを開けません:」と報告されていた場所で、次を使用してヒープダ​​ンプを取得できました。

sudo -u jboss jmap -dump:file.bin <pid>

パラメータをsudoからjmapに渡すときに、-をエスケープする必要があるため、\-dump:file.bin <pid>にする必要があると思います。
アダム2015

これです!jmapとjcmdもsudoする必要があります。
xtian 2016年

うわー..これは実際に働いた。これは受け入れられた答えであるはずです
Lalit Rao

3

ben_wingが言ったように、次のコマンドで実行できます。

sudo -u jboss-as jmap -dump:file.bin <pid>

(私の場合、ユーザーはjboss-asですが、あなたのユーザーは、jbossまたは他のユーザーである可能性があります。)

しかし、他のコマンドでパスワードの入力を求められなくて[sudo] password for ec2-user:も実行できたにもかかわらず、パスワード()を要求されたため、十分ではありませんでしたsudo

私はここで解決策を見つけました、そして私はsudo最初に別のものを追加する必要がありました:

sudo sudo -u jboss-as jmap -dump:file.bin <pid>

のような他のコマンドjcmdjinfoも機能します。


ダブルsudoは私の一日を救います!
Sher10ck

[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 エラーになりますsudo: jmap: command not found。私はすでに.bash_profileでJavaパスを設定しています。どうすればよいですか。
ローマー

@roamerおそらく、esユーザーとして実行したときに、.bash_profileが適用されていないためです(bashプロファイルはユーザーに関連していると思います)。よりグローバルな方法でJavaパスを含めるか、コマンドでJavaパスを指定することをお勧めしますsudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283/java/pathJavaパスはどこにあり、そこにあることを確認jmapしてください)。
ルーカスバスケロット

/home/es/.bash_profileでJavaパスを構成し、esユーザーでログインするときにjmapを使用できます。このコマンドはsudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283機能します。どうもありがとう。
ローマー

2

アプリケーションがsystemdサービスとして実行/usr/lib/systemd/system/されている場合。サービス名の下に名前が付けられたサービスファイルを開く必要があります。次に、privateTmp属性がtrueであるかどうかを確認します。

trueの場合は、falseに変更してから、次のようにコマンドでサービスを更新 systemctl daemon-reload systemctl restart [servicename] する必要があります。再起動する前にjmap / jcmdを実行する場合は、サービスファイルのexecStopスクリプトを使用できます。コマンドを入れて実行するだけですsystemctl stop [service name]


/usr/lib/systemd/system/elasticsearch.serviceを更新し、privateTmpをfalseに設定する前に、次のエラーが発生しました:ソケットファイルを開くことができません:ターゲットプロセスが応答しないか、HotSpotVMがロードされていません-jmapを次のように実行していてもelasticsearchユーザ
imdibiji
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.