1. Overview

jmap, as we know, is a command-line utility included in Linux releases of the Java Development Kit (JDK). We use jmap to capture the heap dump of a running process.

Although the jmap command works in most cases, there may be times when it requires special handling. This is particularly in situations when a target JVM’s process state makes jmap completely dysfunctional.

In this tutorial, we’ll first discuss how jmap works while it creates heap dumps. Then, we’ll discuss a situation when jmap returns an Unable to open socket file error, which is an issue most of us often experience while using it.

2. jmap for Taking Heap Dumps

jmap is one of the command line tools shipped with the JDK. It creates memory-related statistics called a heap dump for a running process.

These stats are usually stored in binary format hprof files. They are required mostly to analyze memory (allocated from the heap) usage by objects in Java applications. This in turn helps diagnose memory-leak problems, provides valuable insight into optimizing memory usage, and realizes reduced performance overhead in Java applications.

Let’s see how we can capture heap dumps using a simple jmap command for a 64-bit JVM:

$ jmap -J-d64 -heap <pid>

Now, let’s look at the use of jmap with the -dump option, which is an option supported with the JDK 7 release onwards. The command causes jmap to dump the Java heap in binary hprof format to the specified file:

$ jmap -dump:[live],format=b,file=<file-path> <pid>

To impart a pleasing appeal to the output, we can also use the options -heap, -histo, or -permstat.

3. The “Unable to Open Socket File” Error

When we try to take a heap dump of a running process, we may sometimes get an error:

$ ./jmap -dump:format=b,file=heap.bin 10661
Unable to open socket file: target process not responding or HotSpot VM not loaded

To understand how this error makes jmap completely dysfunctional, we must first know how it works. So, in short, let’s take a look at how jmap writes heap dumps using Dynamic Attach Mechanism.

Under this mechanism, the heap dump is made in-process directly by the JVM. The jmap command causes the JVM to start an AttachListener thread while all other threads are terminated. This special thread creates a socket for jmap to issue a dumpheap command. The socket captures all the output generated by the command at safepoints, the JVM stop-the-world pause mechanism.

Now, here comes the part that explains the reason behind the error. At this point, if a safepoint is not reached, heap dumps are not written. jmap times out and fails due to a process being hung, not responding, or a long GC being in progress.

The jmap command might also fail and return the error because of other reasons:

  • it’s not run by the same user (euid/egid) as the target JVM
  • the JVM is not a live and healthy JVM
  • the target JVM is started with -XX:+DisableAttachMechanism
  • its JDK version is not the same as that of the target process

4. Using jmap -F Solution

The problem of jmap returning the error Unable to open socket file is usually solved with the -F option or forced mode:

$ ./jmap -F -dump:format=b,file=heap.bin 10661
Attaching to process ID 10661, please wait... 
Debugger attached successfully. 
Server compiler detected. 
JVM version is 24.51-b03 
Dumping heap to heap.bin …

When run in the forced mode, the target process is frozen while jmap switches to a special mode that features HotSpot Serviceability Agent. In this mode, jmap instead reads memory via an OS debugging facility called as ptrace, creates a heap dump itself, and then resumes the target process.

jmap also enforces that the user running the command must be the same user running the process attempting to be dumped. Let’s suppose that the JVM we want a heap dump for is being run by Linux user “Peter”. Here’s how we can capture a heap dump:

$ sudo -u Peter jmap -F -dump:file.bin <pid>

jmap does well when run in this mode, except when it becomes slow for large heaps. It completely fails if the tool and the target JVM don’t have the same JDK version. It will also fail if the target JVM is running in an inconsistent state.

5. Conclusion

In this article, we discussed what the jmap command can do in Linux. Besides learning how the command works, we discussed a situation when it returns an Unable to open socket file error. Then, we saw what makes it fail along with ways to solve the problem.