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 runsfinalize
method of the objects ready to be finalized.Signal Dispatcher
waits for specific OS signals and handles them. In particular, it makes thread dump onSIGQUIT
, and also initiates VM shutdown process onSIGTERM
,SIGINT
andSIGHUP
.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 ofjava.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 byjstack
,jmap
andjcmd
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
Javax.* Cannot Be Imported in My Android App
Background Service for Android Oreo
How to Find Java Heap Size and Memory Used (Linux)
Encrypt in Ruby and Decrypt in Java - Why Is It Not Working
Convert Existing Eclipse Project to Maven Project
Sockets: Discover Port Availability Using Java
How to Convert an Array to a Set in Java
Should I Keep My Project Files Under Version Control
Emulate Annotation Inheritance for Interfaces and Methods with Aspectj
Java 7 (Jdk 7) Garbage Collection and Documentation on G1
Change Background Color of Single Specific Menu Items of Navigationview
Database Not Copying from Assets
Ubuntu: Openjdk 8 - Unable to Locate Package
Compute Hex Color Code for an Arbitrary String
Access Restriction: the Type 'Application' Is Not API (Restriction on Required Library Rt.Jar)
Generate All Combinations from Multiple Lists