Command to check the number and status of Java threads

When maintaining and operating a Java application server, you may want to know the number and status of currently running threads. I think that a general Java application server comes with some kind of health check function, but depending on the situation, such a function may not be available. How can I know the number and status of threads in such a situation?

Example

The following Server.java is a program that imitates a Java application server and forks three child threads.

Server.java


import java.util.ArrayList;
import java.util.List;

public class Server{
    public static void main(String[] args) throws InterruptedException {
        //Fork 3 child threads.
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 3	; i++) {
            Thread thread = new Thread(() -> sleepForever());
            thread.start();
            threads.add(thread);
        }

        //Put the parent thread itself to sleep.
        sleepForever();
    }

    private static void sleepForever() {
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Compile this and run it.

$ java Server &
[1] 404

(1) jstack

If you want to know the number and status of threads, jstack is probably the best. jstack is a command that comes with the JDK, so if you have a system that uses a Java application server, you should be able to use it in many cases.

The following is an example of executing jstack. You can see that in addition to the main thread and its child threads Thread-0`` Thread-1`` Thread-2, the status of some threads used by the jvm is displayed along with the stack trace.

$ jstack 404
2019-12-26 00:06:09
Full thread dump OpenJDK 64-Bit Server VM (11.0.4+11-post-Ubuntu-1ubuntu218.04.3 mixed mode, sharing):

Threads class SMR info:
_java_thread_list=0x00007f6a280029d0, length=13, elements={
0x00007f6a74011800, 0x00007f6a74165000, 0x00007f6a74167000, 0x00007f6a7416f800,
0x00007f6a74171800, 0x00007f6a74174000, 0x00007f6a74176000, 0x00007f6a741d8800,
0x00007f6a741e2000, 0x00007f6a741f1800, 0x00007f6a741f3800, 0x00007f6a741f5000,
0x00007f6a28001000
}

"main" #1 prio=5 os_prio=0 cpu=90.00ms elapsed=496.33s tid=0x00007f6a74011800 nid=0x195 waiting on condition  [0x00007f6a7b56f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep([email protected]/Native Method)
        at Server.sleepForever(Server.java:20)
        at Server.main(Server.java:15)

"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=0.00ms elapsed=496.30s tid=0x00007f6a74165000 nid=0x19c waiting on condition  [0x00007f6a58adf000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.ref.Reference.waitForReferencePendingList([email protected]/Native Method)
        at java.lang.ref.Reference.processPendingReferences([email protected]/Reference.java:241)
        at java.lang.ref.Reference$ReferenceHandler.run([email protected]/Reference.java:213)

"Finalizer" #3 daemon prio=8 os_prio=0 cpu=0.00ms elapsed=496.30s tid=0x00007f6a74167000 nid=0x19d in Object.wait()  [0x00007f6a589cf000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait([email protected]/Native Method)
        - waiting on <0x000000074e50a2c8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove([email protected]/ReferenceQueue.java:155)
        - waiting to re-lock in wait() <0x000000074e50a2c8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove([email protected]/ReferenceQueue.java:176)
        at java.lang.ref.Finalizer$FinalizerThread.run([email protected]/Finalizer.java:170)

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

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

"C1 CompilerThread0" #8 daemon prio=9 os_prio=0 cpu=30.00ms elapsed=496.29s tid=0x00007f6a74174000 nid=0x1a0 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

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

"Service Thread" #10 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=496.27s tid=0x00007f6a741d8800 nid=0x1a2 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Common-Cleaner" #11 daemon prio=8 os_prio=0 cpu=0.00ms elapsed=496.26s tid=0x00007f6a741e2000 nid=0x1a4 in Object.wait()  [0x00007f6a17fef000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait([email protected]/Native Method)
        - waiting on <0x000000074e416e98> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove([email protected]/ReferenceQueue.java:155)
        - waiting to re-lock in wait() <0x000000074e416e98> (a java.lang.ref.ReferenceQueue$Lock)
        at jdk.internal.ref.CleanerImpl.run([email protected]/CleanerImpl.java:148)
        at java.lang.Thread.run([email protected]/Thread.java:834)
        at jdk.internal.misc.InnocuousThread.run([email protected]/InnocuousThread.java:134)

"Thread-0" #12 prio=5 os_prio=0 cpu=0.00ms elapsed=496.25s tid=0x00007f6a741f1800 nid=0x1a5 waiting on condition  [0x00007f6a17a9f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep([email protected]/Native Method)
        at Server.sleepForever(Server.java:20)
        at Server.lambda$0(Server.java:9)
        at Server$$Lambda$1/0x0000000840060840.run(Unknown Source)
        at java.lang.Thread.run([email protected]/Thread.java:834)

"Thread-1" #13 prio=5 os_prio=0 cpu=0.00ms elapsed=496.25s tid=0x00007f6a741f3800 nid=0x1a6 waiting on condition  [0x00007f6a1798f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep([email protected]/Native Method)
        at Server.sleepForever(Server.java:20)
        at Server.lambda$0(Server.java:9)
        at Server$$Lambda$1/0x0000000840060840.run(Unknown Source)
        at java.lang.Thread.run([email protected]/Thread.java:834)

"Thread-2" #14 prio=5 os_prio=0 cpu=0.00ms elapsed=496.25s tid=0x00007f6a741f5000 nid=0x1a7 waiting on condition  [0x00007f6a1787f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep([email protected]/Native Method)
        at Server.sleepForever(Server.java:20)
        at Server.lambda$0(Server.java:9)
        at Server$$Lambda$1/0x0000000840060840.run(Unknown Source)
        at java.lang.Thread.run([email protected]/Thread.java:834)

"Attach Listener" #15 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=0.10s tid=0x00007f6a28001000 nid=0x1dc waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"VM Thread" os_prio=0 cpu=0.00ms elapsed=496.31s tid=0x00007f6a74162000 nid=0x19b runnable

"GC Thread#0" os_prio=0 cpu=0.00ms elapsed=496.32s tid=0x00007f6a74028000 nid=0x196 runnable

"G1 Main Marker" os_prio=0 cpu=0.00ms elapsed=496.32s tid=0x00007f6a74070800 nid=0x197 runnable

"G1 Conc#0" os_prio=0 cpu=0.00ms elapsed=496.32s tid=0x00007f6a74072800 nid=0x198 runnable

"G1 Refine#0" os_prio=0 cpu=0.00ms elapsed=496.32s tid=0x00007f6a74138000 nid=0x199 runnable

"G1 Young RemSet Sampling" os_prio=0 cpu=0.00ms elapsed=496.32s tid=0x00007f6a74139800 nid=0x19a runnable
"VM Periodic Task Thread" os_prio=0 cpu=0.00ms elapsed=496.27s tid=0x00007f6a741db000 nid=0x1a3 waiting on condition

JNI global refs: 6, weak refs: 0

(2) ps

Java on Linux delegates threading to the OS's native threads. In other words, there is a relationship of "Java thread" = "OS thread". Therefore, if you use a command that can check the status of OS threads, you can indirectly check the status of Java threads.

There are several ways to check the status of OS threads, but the most versatile and useful one is ps. The execution example is as follows. The amount of information such as thread name and stack trace is smaller than that of jstack, but this is enough for simple confirmation.

$ ps -L mu 404
USER       PID   LWP %CPU NLWP %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
dev        404     -  0.0   21  0.2 6100336 25820 tty1    -    Dec25   0:00 java Server
dev          -   404  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   405  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   406  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   407  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   408  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   409  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   410  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   411  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   412  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   413  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   414  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   415  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   416  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   417  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   418  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   419  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   420  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   421  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   422  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   423  0.0    -    -      -     - -        Sl   Dec25   0:00 -
dev          -   476  0.0    -    -      -     - -        Sl   00:06   0:00 -

reference

This article has been confirmed to work in the following environment.

software version
OS Ubuntu 18.04.2 LTS (Windows Subsystem for Linux)
JDK openjdk 11.0.4 2019-07-16
ps ps from procps-ng 3.3.12

Recommended Posts

Command to check the number and status of Java threads
[Java] Check the number of occurrences of characters
I tried to summarize the basics of kotlin and java
Check the status of Java application without using monitoring tool
Check the migration status of rails
How to check the extension and size of uploaded files
[Java] Various summaries attached to the heads of classes and members
Method to add the number of years and get the end of the month
From fledgling Java (3 years) to Node.js (4 years). And the impression of returning to Java
I tried to summarize the methods of Java String and StringBuilder
How to check for the contents of a java fixed-length string
Check the contents of the Java certificate store
Memo: [Java] Check the contents of the directory
How to determine the number of parallels
Output of the book "Introduction to Java"
About the number of threads of Completable Future
Check the operation of the interface through threads
The story of forgetting to close a file in Java and failing
How to change the maximum and maximum number of POST data in Spark
How to find the total number of pages when paging in Java
[Java improvement case] How to reach the limit of self-study and beyond
I translated the grammar of R and Java [Updated from time to time]
Check the version of the JDK installed and the version of the JDK enabled
[Java] The confusing part of String and StringBuilder
I compared the characteristics of Java and .NET
Basics of threads and Callable in Java [Beginner]
Compile and run Java on the command line
[Java] How to get the authority of the folder
Java Welcome to the Swamp of 2D Arrays
I want to create an ExecutorService that increases or decreases the number of threads depending on the task status and sets an upper limit on the number of threads.
Differences between Java, C # and JavaScript (how to determine the degree of obesity)
[Java] Is it unnecessary to check "identity" in the implementation of the equals () method?
Introduction to java command
[Java] How to get the URL of the transition source
[Java] Types of comments and how to write them
Please note the division (division) of java kotlin Int and Int
Check the capacity of the Linux server. (Df command, du command)
[Java] Check the JDK version of the built war file
Convert the array of errors.full_messages to characters and output
Organizing the current state of Java and considering the future
Java language from the perspective of Kotlin and C #
[Java] How to get the maximum value of HashMap
Check the behavior of Java Intrinsic Locks with bpftrace
Java classes and instances to understand in the figure
I summarized the types and basics of Java exceptions
Java: Use Stream to sort the contents of the collection
Check the rate limit application status of docker pull
Limit the number of threads using Java's Executor Service
A memo about the types of Java O/R mappers and how to select them
[Note] Java Output of the sum of odd and even elements
Generate and execute Jar file of Java file belonging to package
Difference between Java and JavaScript (how to find the average)
Get to the abbreviations from 5 examples of iterating Java lists
[Ruby] Questions and verification about the number of method arguments
20190803_Java & k8s on Azure The story of going to the festival
I want to call a method and count the number
Java beginners briefly summarized the behavior of Array and ArrayList
[Java] To know the type information of type parameters at runtime
Count the number of digits after the decimal point in Java
[Java] Check the difference between orElse and orElseGet with IntStream
Advantages and disadvantages of Java