运行jmap无法打开套接字文件

时间:2022-01-19 17:20:15

I had to run jmap in order to take heap dump of my process. but jvm returned:

我必须运行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

So I used the -F:

我用-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. Using -F is allright for taking heap dump?
  2. 使用-F可以获取堆转储吗?
  3. I am waiting 20 minutes and not finished yet. Any ideas why?
  4. 我正在等20分钟,还没做完。任何想法为什么?

3 个解决方案

#1


101  

jmap vs. jmap -F, as well as jstack vs. jstack -F use completely different mechanisms to communcate with the target JVM.

jmap和jmap -F以及jstack和jstack -F使用完全不同的机制与目标JVM进行通信。

jmap / jstack

When run without -F these tools use Dynamic Attach Mechanism. This works as follows.

当没有-F运行时,这些工具使用动态附加机制。其工作原理如下。

  1. Before connecting to Java process 1234, jmap creates a file .attach_pid1234 at the working directory of the target process or at /tmp.

    在连接到Java进程1234之前,jmap在目标进程的工作目录或/tmp上创建一个.attach_pid1234文件。

  2. Then jmap sends SIGQUIT to the target process. When JVM catches the signal and finds .attach_pid1234, it starts AttachListener thread.

    然后jmap将SIGQUIT发送到目标进程。当JVM捕获到信号并找到.attach_pid1234时,它将启动AttachListener线程。

  3. AttachListener thread creates UNIX domain socket /tmp/.java_pid1234 to listen to commands from external tools.

    AttachListener线程创建UNIX域套接字/tmp/。java_pid1234用于侦听来自外部工具的命令。

  4. For security reasons when a connection (from jmap) is accepted, JVM verifies that credentials of the socket peer are equal to euid and egid of JVM process. That's why jmap will not work if run by different user (even by root).

    出于安全原因,当接受连接(来自jmap)时,JVM验证套接字对等点的凭据是否等于JVM进程的euid和egid。这就是为什么如果由不同的用户(甚至是根用户)运行jmap将无法工作。

  5. jmap connects to the socket, and sends dumpheap command.

    jmap连接到套接字,并发送dumpheap命令。

  6. This command is read and executed by AttachListener thread of the JVM. All output is sent back to the socket. Since the heap dump is made in-process directly by JVM, the operation is really fast. However, JVM can do this only at safepoints. If a safepoint cannot be reached (e.g. the process is hung, not responding, or a long GC is in progress), jmap will timeout and fail.

    这个命令是由JVM的AttachListener线程读取和执行的。所有输出都被发送回套接字。由于堆转储是由JVM直接在进程中生成的,所以操作非常快。但是,JVM只能在安全点上执行此操作。如果无法到达某个安全点(例如,进程挂起,没有响应,或者长时间GC正在进行中),jmap将超时并失败。

Let's summarize the benefits and the drawbacks of Dynamic Attach.

让我们总结一下动态附加的优点和缺点。

Pros.

优点。

  • Heap dump and other operations are run collaboratively by JVM at the maximum speed.
  • 堆转储和其他操作由JVM以最大速度协同运行。
  • You can use any version of jmap or jstack to connect to any other version of JVM.
  • 您可以使用任何版本的jmap或jstack来连接到任何其他版本的JVM。

Cons.

缺点。

  • The tool should be run by the same user (euid/egid) as the target JVM.
  • 工具应该由与目标JVM相同的用户(euid/egid)运行。
  • Can be used only on live and healthy JVM.
  • 只能在活动的和健康的JVM上使用。
  • Will not work if the target JVM is started with -XX:+DisableAttachMechanism.
  • 如果目标JVM是用-XX:+DisableAttachMechanism启动的,那么它将不会工作。

jmap -F / jstack -F

When run with -F the tools switch to special mode that features HotSpot Serviceability Agent. In this mode the target process is frozen; the tools read its memory via OS debugging facilities, namely, ptrace on Linux.

当使用-F运行时,工具切换到具有HotSpot服务能力代理的特殊模式。在这种模式下,目标进程被冻结;这些工具通过OS调试工具(即Linux上的ptrace)读取内存。

  1. jmap -F invokes PTRACE_ATTACH on the target JVM. The target process is unconditionally suspended in response to SIGSTOP signal.

    jmap -F在目标JVM上调用PTRACE_ATTACH。目标进程被无条件地暂停,以响应SIGSTOP信号。

  2. The tool reads JVM memory using PTRACE_PEEKDATA. ptrace can read only one word at a time, so too many calls required to read the large heap of the target process. This is very and very slow.

    该工具使用PTRACE_PEEKDATA读取JVM内存。ptrace一次只能读取一个单词,因此读取目标进程的大堆所需的调用太多。这是非常非常缓慢的。

  3. The tool reconstructs JVM internal structures based on the knowledge of the particular JVM version. Since different versions of JVM have different memory layout, -F mode works only if jmap comes from the same JDK as the target Java process.

    该工具基于特定JVM版本的知识重构JVM内部结构。由于不同版本的JVM有不同的内存布局,只有当jmap来自与目标Java进程相同的JDK时,-F模式才有效。

  4. The tool creates heap dump itself and then resumes the target process.

    该工具创建堆转储本身,然后继续目标进程。

Pros.

优点。

  • No cooperation from target JVM is required. Can be used even on a hung process.
  • 不需要来自目标JVM的合作。甚至可以在挂起的进程中使用。
  • ptrace works whenever OS-level privileges are enough. E.g. root can dump processes of all other users.
  • 当操作系统级特权足够时,ptrace就会工作。root可以转储所有其他用户的进程。

Cons.

缺点。

  • Very slow for large heaps.
  • 大堆的速度很慢。
  • The tool and the target process should be from the same version of JDK.
  • 工具和目标进程应该来自同一版本的JDK。
  • The safepoint is not guaranteed when the tool attaches in forced mode. Though jmap tries to handle all special cases, sometimes it may happen that target JVM is not in a consistent state.
  • 当工具以强制模式连接时,安全点没有保证。尽管jmap试图处理所有的特殊情况,但有时目标JVM可能并不处于一致的状态。

Note

请注意

There is a faster way to take heap dumps in forced mode. First, create a coredump with gcore, then run jmap over the generated core file. See the related question.

有一种更快的方法可以在强制模式下进行堆转储。首先,使用gcore创建一个coredump,然后在生成的核心文件上运行jmap。看到相关的问题。

#2


62  

I just found that jmap (and presumably jvisualvm when using it to generate a heap dump) enforces that the user running jmap must be the same user running the process attempting to be dumped.

我刚刚发现jmap(大概是jvisualvm在使用它生成堆转储时)强制运行jmap的用户必须是运行要转储的进程的同一用户。

in my case the jvm i want a heap dump for is being run by linux user "jboss". so where sudo jmap -dump:file.bin <pid> was reporting "Unable to open socket:", i was able to grab my heap dump using:

在我的例子中,我希望堆转储用于的jvm是由linux用户“jboss”运行的。这里是sudo jmap -dump:file。bin 报告“无法打开套接字:”,我可以使用:

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

#3


0  

Just like ben_wing said, you can run with:

就像ben_wing说的,你可以用:

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

(in my case the user is jboss-as, but yours could be jboss or some other.)

(在我的例子中,用户是jboss-as,但是您的用户可以是jboss或其他类型的。)

But it was not enough, because it asked me for a password ([sudo] password for ec2-user:), although I could run sudo without prompting me for a password with other commands.

但这还不够,因为它要求我输入ec2-user:的密码([sudo] password),尽管我可以运行sudo而不需要提示我输入其他命令的密码。

I found the solution here, and I just needed to add another sudo first:

我在这里找到了解决方案,我只需要先添加一个sudo:

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

It works with other commands like jcmd and jinfo too.

它还可以与jcmd和jinfo等其他命令一起使用。

#1


101  

jmap vs. jmap -F, as well as jstack vs. jstack -F use completely different mechanisms to communcate with the target JVM.

jmap和jmap -F以及jstack和jstack -F使用完全不同的机制与目标JVM进行通信。

jmap / jstack

When run without -F these tools use Dynamic Attach Mechanism. This works as follows.

当没有-F运行时,这些工具使用动态附加机制。其工作原理如下。

  1. Before connecting to Java process 1234, jmap creates a file .attach_pid1234 at the working directory of the target process or at /tmp.

    在连接到Java进程1234之前,jmap在目标进程的工作目录或/tmp上创建一个.attach_pid1234文件。

  2. Then jmap sends SIGQUIT to the target process. When JVM catches the signal and finds .attach_pid1234, it starts AttachListener thread.

    然后jmap将SIGQUIT发送到目标进程。当JVM捕获到信号并找到.attach_pid1234时,它将启动AttachListener线程。

  3. AttachListener thread creates UNIX domain socket /tmp/.java_pid1234 to listen to commands from external tools.

    AttachListener线程创建UNIX域套接字/tmp/。java_pid1234用于侦听来自外部工具的命令。

  4. For security reasons when a connection (from jmap) is accepted, JVM verifies that credentials of the socket peer are equal to euid and egid of JVM process. That's why jmap will not work if run by different user (even by root).

    出于安全原因,当接受连接(来自jmap)时,JVM验证套接字对等点的凭据是否等于JVM进程的euid和egid。这就是为什么如果由不同的用户(甚至是根用户)运行jmap将无法工作。

  5. jmap connects to the socket, and sends dumpheap command.

    jmap连接到套接字,并发送dumpheap命令。

  6. This command is read and executed by AttachListener thread of the JVM. All output is sent back to the socket. Since the heap dump is made in-process directly by JVM, the operation is really fast. However, JVM can do this only at safepoints. If a safepoint cannot be reached (e.g. the process is hung, not responding, or a long GC is in progress), jmap will timeout and fail.

    这个命令是由JVM的AttachListener线程读取和执行的。所有输出都被发送回套接字。由于堆转储是由JVM直接在进程中生成的,所以操作非常快。但是,JVM只能在安全点上执行此操作。如果无法到达某个安全点(例如,进程挂起,没有响应,或者长时间GC正在进行中),jmap将超时并失败。

Let's summarize the benefits and the drawbacks of Dynamic Attach.

让我们总结一下动态附加的优点和缺点。

Pros.

优点。

  • Heap dump and other operations are run collaboratively by JVM at the maximum speed.
  • 堆转储和其他操作由JVM以最大速度协同运行。
  • You can use any version of jmap or jstack to connect to any other version of JVM.
  • 您可以使用任何版本的jmap或jstack来连接到任何其他版本的JVM。

Cons.

缺点。

  • The tool should be run by the same user (euid/egid) as the target JVM.
  • 工具应该由与目标JVM相同的用户(euid/egid)运行。
  • Can be used only on live and healthy JVM.
  • 只能在活动的和健康的JVM上使用。
  • Will not work if the target JVM is started with -XX:+DisableAttachMechanism.
  • 如果目标JVM是用-XX:+DisableAttachMechanism启动的,那么它将不会工作。

jmap -F / jstack -F

When run with -F the tools switch to special mode that features HotSpot Serviceability Agent. In this mode the target process is frozen; the tools read its memory via OS debugging facilities, namely, ptrace on Linux.

当使用-F运行时,工具切换到具有HotSpot服务能力代理的特殊模式。在这种模式下,目标进程被冻结;这些工具通过OS调试工具(即Linux上的ptrace)读取内存。

  1. jmap -F invokes PTRACE_ATTACH on the target JVM. The target process is unconditionally suspended in response to SIGSTOP signal.

    jmap -F在目标JVM上调用PTRACE_ATTACH。目标进程被无条件地暂停,以响应SIGSTOP信号。

  2. The tool reads JVM memory using PTRACE_PEEKDATA. ptrace can read only one word at a time, so too many calls required to read the large heap of the target process. This is very and very slow.

    该工具使用PTRACE_PEEKDATA读取JVM内存。ptrace一次只能读取一个单词,因此读取目标进程的大堆所需的调用太多。这是非常非常缓慢的。

  3. The tool reconstructs JVM internal structures based on the knowledge of the particular JVM version. Since different versions of JVM have different memory layout, -F mode works only if jmap comes from the same JDK as the target Java process.

    该工具基于特定JVM版本的知识重构JVM内部结构。由于不同版本的JVM有不同的内存布局,只有当jmap来自与目标Java进程相同的JDK时,-F模式才有效。

  4. The tool creates heap dump itself and then resumes the target process.

    该工具创建堆转储本身,然后继续目标进程。

Pros.

优点。

  • No cooperation from target JVM is required. Can be used even on a hung process.
  • 不需要来自目标JVM的合作。甚至可以在挂起的进程中使用。
  • ptrace works whenever OS-level privileges are enough. E.g. root can dump processes of all other users.
  • 当操作系统级特权足够时,ptrace就会工作。root可以转储所有其他用户的进程。

Cons.

缺点。

  • Very slow for large heaps.
  • 大堆的速度很慢。
  • The tool and the target process should be from the same version of JDK.
  • 工具和目标进程应该来自同一版本的JDK。
  • The safepoint is not guaranteed when the tool attaches in forced mode. Though jmap tries to handle all special cases, sometimes it may happen that target JVM is not in a consistent state.
  • 当工具以强制模式连接时,安全点没有保证。尽管jmap试图处理所有的特殊情况,但有时目标JVM可能并不处于一致的状态。

Note

请注意

There is a faster way to take heap dumps in forced mode. First, create a coredump with gcore, then run jmap over the generated core file. See the related question.

有一种更快的方法可以在强制模式下进行堆转储。首先,使用gcore创建一个coredump,然后在生成的核心文件上运行jmap。看到相关的问题。

#2


62  

I just found that jmap (and presumably jvisualvm when using it to generate a heap dump) enforces that the user running jmap must be the same user running the process attempting to be dumped.

我刚刚发现jmap(大概是jvisualvm在使用它生成堆转储时)强制运行jmap的用户必须是运行要转储的进程的同一用户。

in my case the jvm i want a heap dump for is being run by linux user "jboss". so where sudo jmap -dump:file.bin <pid> was reporting "Unable to open socket:", i was able to grab my heap dump using:

在我的例子中,我希望堆转储用于的jvm是由linux用户“jboss”运行的。这里是sudo jmap -dump:file。bin 报告“无法打开套接字:”,我可以使用:

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

#3


0  

Just like ben_wing said, you can run with:

就像ben_wing说的,你可以用:

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

(in my case the user is jboss-as, but yours could be jboss or some other.)

(在我的例子中,用户是jboss-as,但是您的用户可以是jboss或其他类型的。)

But it was not enough, because it asked me for a password ([sudo] password for ec2-user:), although I could run sudo without prompting me for a password with other commands.

但这还不够,因为它要求我输入ec2-user:的密码([sudo] password),尽管我可以运行sudo而不需要提示我输入其他命令的密码。

I found the solution here, and I just needed to add another sudo first:

我在这里找到了解决方案,我只需要先添加一个sudo:

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

It works with other commands like jcmd and jinfo too.

它还可以与jcmd和jinfo等其他命令一起使用。