How Do Jps, Jinfo, Jstat, Jmap and Jstack Get Information About Local Java Processes

How do jps, jinfo, jstat, jmap and jstack get information about local Java processes?

jps finds running Java processes by scanning through /tmp/hsperfdata_<username> directory. Each HotSpot-based Java process creates a file in this directory with the name equal to the process ID.

The file /tmp/hsperfdata_<username>/<pid> contains various counters exported by the JVM. These counters can be read by an external process. This is exactly how jstat works. I described jvmstat performance counters in the JavaMagazine article.

So, jstat can always read counters of a local Java process, but in order to be able to monitor a remote machine, jstatd needs to be running.

jmap, jstack and jinfo use Dynamic Attach mechanism. These utilities connect to the target JVM via UNIX-domain socket and send the corresponding command to the JVM. The command is executed by the remote JVM itself. Find more about Dynamic Attach in this answer and in this presentation.

Commands like jps, jstat, jstack, etc show pid not found

In Ubuntu 20 the Tomcat 9 service runs in a private tmp space by default and because of that the java tools cannot find its pid.

This private tmp setting is defined in /lib/systemd/system/tomcat9.service as PrivateTmp. It is set to "yes" by default. You could edit that file directly but the recommended way to make changes is to create an override file using this command:

sudo systemctl edit tomcat9

Add the following content to the file and save:

[Service]
PrivateTmp=no
ReadWritePaths=/tmp/

It will create this file with your content: /etc/systemd/system/tomcat9.service.d/override.conf

Then you need to reload the systemd daemon and restart Tomcat:

sudo systemctl daemon-reload
sudo systemctl restart tomcat9

You should now be able to call the java tools using sudo directly, e.g. sudo jstat.... For some reason it does not work when I try to run it as the tomcat user with sudo -u tomcat jstat...

how does jconsole/visualvm know local running java apps

Quoting from the VisualVM documentation (it is described in the When Are Explicit JMX Connections Necessary? section and concerns local instances):

Java VisualVM discovers running applications using the jps tool (Solaris, Linux, or Mac OS X or Windows), which can only discover Java applications started by the same user as the one who starts the Java VisualVM tool.

Info about how jps discovers local VMs is, for example, in this SO answer. In short, it scans the /tmp/hsperfdata_<username> directory, where JVM instances generate info files.

Jmap can't connect to make a dump

The solution was very simple. I was running the jmap as root, but I had to run it as the user who started the jvm. I will now go hide my head in shame.

What are threads (i.e. lightweight processes) named `{java}` created for?

All of these threads belong to JVM.

Run jstack <pid> to get the thread list.

"main" #1 prio=5 os_prio=0 cpu=150.00ms elapsed=8.04s tid=0x00007f9f90011000 nid=0x107 waiting on condition  [0x00007f9f99f9f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(java.base@11.0.1/Native Method)
at java.lang.Thread.sleep(java.base@11.0.1/Thread.java:339)
at java.util.concurrent.TimeUnit.sleep(java.base@11.0.1/TimeUnit.java:446)
at com.mycompany.app.Main.main(Main.java:10)

"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=0.00ms elapsed=7.95s tid=0x00007f9f901f9000 nid=0x10e waiting on condition [0x00007f9f6c10f000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@11.0.1/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.1/Reference.java:213)

"Finalizer" #3 daemon prio=8 os_prio=0 cpu=0.00ms elapsed=7.95s tid=0x00007f9f901fd800 nid=0x10f in Object.wait() [0x00007f9f65fef000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@11.0.1/Native Method)
- waiting on <0x0000000712108f80> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:155)
- waiting to re-lock in wait() <0x0000000712108f80> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:176)
at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.1/Finalizer.java:170)

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=7.93s tid=0x00007f9f90210000 nid=0x110 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 cpu=40.00ms elapsed=7.93s tid=0x00007f9f90212000 nid=0x111 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task

"C1 CompilerThread0" #7 daemon prio=9 os_prio=0 cpu=40.00ms elapsed=7.93s tid=0x00007f9f90214000 nid=0x112 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task

"Sweeper thread" #8 daemon prio=9 os_prio=0 cpu=10.00ms elapsed=7.93s tid=0x00007f9f90216000 nid=0x113 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Service Thread" #9 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=7.90s tid=0x00007f9f902d3800 nid=0x114 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Common-Cleaner" #10 daemon prio=8 os_prio=0 cpu=0.00ms elapsed=7.89s tid=0x00007f9f902df800 nid=0x116 in Object.wait() [0x00007f9f656ef000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(java.base@11.0.1/Native Method)
- waiting on <0x0000000712002df0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:155)
- waiting to re-lock in wait() <0x0000000712002df0> (a java.lang.ref.ReferenceQueue$Lock)
at jdk.internal.ref.CleanerImpl.run(java.base@11.0.1/CleanerImpl.java:148)
at java.lang.Thread.run(java.base@11.0.1/Thread.java:834)
at jdk.internal.misc.InnocuousThread.run(java.base@11.0.1/InnocuousThread.java:134)

"Attach Listener" #11 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=0.21s tid=0x00007f9f44001000 nid=0x126 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"VM Thread" os_prio=0 cpu=0.00ms elapsed=7.95s tid=0x00007f9f901f1000 nid=0x10d runnable

"GC Thread#0" os_prio=0 cpu=0.00ms elapsed=8.01s tid=0x00007f9f90038800 nid=0x108 runnable

"G1 Main Marker" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f90097800 nid=0x109 runnable

"G1 Conc#0" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f90099800 nid=0x10a runnable

"G1 Refine#0" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f9018d000 nid=0x10b runnable

"G1 Young RemSet Sampling" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f9018f000 nid=0x10c runnable
"VM Periodic Task Thread" os_prio=0 cpu=0.00ms elapsed=7.90s tid=0x00007f9f902d6000 nid=0x115 waiting on condition

Here nid is the hexadecimal ID of a thread in the OS - you may match it to the output of pstree.

  • The first thread named main is the thread executing your code.

  • Reference Handler thread is responsible for adding Weak, Soft and Phantom references discovered by Garbage Collector into their registered ReferenceQueues.

  • Finalizer thread runs finalize method of the objects ready to be finalized.

  • Signal Dispatcher waits for specific OS signals and handles them. In particular, it makes thread dump on SIGQUIT, and also initiates VM shutdown process on SIGTERM, SIGINT and SIGHUP.

  • CompilerThreads perform JIT compilation of the bytecode.

  • Sweeper thread cleans up obsolete compiled methods.

  • Service Thread runs several background JVM tasks: detects low memory condition, cleans up StringTable and SymbolTable, sends deferred JVMTI events and GC notifications and so on.

  • Common-Cleaner runs cleaning actions of java.lang.ref.Cleaner instances.

  • Attach Listener thread supports Dynamic Attach mechanism. It listens for incoming Dynamic Attach connections and executes VM commands. For example, it is used by jstack, jmap and jcmd utilities.

  • VM Thread runs internal VM operations that require a safepoint. The examples of such operations are deoptimization, class redifinition, biased lock revocation, thread dump, heap inspection etc.

  • G1 threads are involved in Garbage Collection.

  • VM Periodic Task Thread is used to simulate timer interrupts.

Getting the parameters of a running JVM

You can use jps like:

jps -lvm

It prints something like:

4050 com.intellij.idea.Main -Xms128m -Xmx512m -XX:MaxPermSize=250m -ea -Xbootclasspath/a:../lib/boot.jar -Djb.restart.code=88
4667 sun.tools.jps.Jps -lvm -Dapplication.home=/opt/java/jdk1.6.0_22 -Xms8m


Related Topics



Leave a reply



Submit