It turns out that jdk comes with such a fun tool - use jstack to locate the infinite loop

A thread snapshot is a collection of method stacks being executed by each thread in the Java virtual machine. The main purpose of generating a thread snapshot is to locate the location of thread problems; common problems include

Command format

There are not many option parameters in jstack, only three are actually used. Next, we will introduce them one by one

- -F: When the thread hangs (Suspended), using the jstack -l pid command will not print the stack information. Using -F can force the thread stack to be output; but it will stop.

- -l: The information printed is except the stack. , additional information about the lock will also be displayed;

- -m: Output the stack information of java and C/C at the same time; in the java system class library, there are many methods that are modified by native. These native You cannot see the source code of the modified methods at the Java level, because these methods are implemented in C/C;

In the thread stack, you need to pay special attention to the following states:

Command without option parameter

The print result is as follows

Analysis of each word in the first line,

Here we use 2 windows, respectively Use the following two commands to test

By comparing the two windows, you can see that the command with -l prints more lock information;

Generally, if the program goes wrong , will not directly find errors on the server in the production environment. At this time, you can use a very practical function to export the stack snapshot, and then copy it to another computer for viewing. The command is as follows

After execution, you can see that the file has been exported

You can see it through the cat command. The content inside is the same as what we output on the command line

First we prepare For an infinite loop thread, define an infinite loop of while in the thread, and give this thread a name: yexindogn. There is a provision in Alibaba's development specifications that each thread must have a name. The name is for It will be easier to find errors when there is a problem with the program in the future;

Then we package this code into a jar package and throw it on the Linux server for running. Directly enter the java -jar Test.jar command to run. After running, we can See that the console has been outputting the character 112, which means that the program is already running;

Then check the running status of the CPU, use the top command to check the CPU usage, the one ranked first It is a process with process number 30328, occupying 6.6 CPU; Here I use 2 command lines to connect to the same server, one window is used to run the jar package just now, and the other window is used to find errors;

Now that we know the process number, we need to find the thread. Enter the following command

The print result is as follows. There is one thing to note here. After we add the -Hp command, the PID displayed is the ID of the thread. , at this time we see that the thread ID with the highest CPU usage is 30365;

There is another way, which is to use the ps command to find the thread

Through this command we can see The thread ID with the highest CPU usage here is also 30365;

Using the above method, we successfully found that the thread ID with the highest CPU usage is 30365, but this ID is in decimal and needs to be converted to hexadecimal first. , enter the command

The corresponding hexadecimal value is calculated as: 769d

Of course, you can also use other

Calculation tools, such as the calculator that comes with the mac system, support conversion between bases

Enter the following command on the command line. This method is faster and recommended.

Among them, grep The command is to find the content whose result is 769d. -A 20 means to print the content of the next 20 lines of the matching line. Directly help us locate the stack of the thread we are in, and the results are as follows

Of course, you can also use the following dead method to print out all the stack snapshots first;

The printing results are as follows

Then I copied the hexadecimal number I just calculated and searched it here. After checking it, I found out that the thread we just named yexindong made an error. The error location was in the 13th line of code in Test.java

Let’s take a look at the java code. It is indeed caused by the infinite loop in line 13.

First open the task manager, because the default Windows task manager does not display the process pid. So we need to set it up, select View Selection Column (S)...

Select the PID process indicator and click the OK button

Then we can see the java that takes up the highest CPU The process PID is: 976

Because Windows cannot directly view the thread information in the java process, we need to use a tool. This tool was developed by Microsoft itself and is called Process Explorer. There are many on the Internet. Please contact us if you need it. Go to Baidu, open it and find the process with pid 976, right-click and select Properties

Find the thread column in the pop-up window. By default, it is sorted in reverse order according to the CPU usage rate, so the top It is the thread that takes up the most CPU. Remember its thread ID: 3548

The process ID we just got is in decimal, but in the jstack information we exported, the thread ID is in hexadecimal. shown, so we need to first convert the thread ID 3548 to hexadecimal, use the calculator that comes with Windows, enter calc on the shortcut command line

After opening the calculator, set it Calculator for programmers

Then enter the thread id3548, click the hexadecimal number, it will automatically convert, the result is ddc, remember this hexadecimal number;

Enter the following command on the command line to export the stack snapshot information of the process

After a few seconds, the snapshot is exported and lies quietly in the folder, waiting for us to open it

Use Notepad Open the exported file and search for the hexadecimal ddc just calculated, and you can locate the location of the thread error

Some children may find it troublesome to use this jstack command. Can java be included in the code? What about printing out the stack? Don't tell me, there really is, it's this method: Thread.getAllStackTraces(); just talk and don't practice the trick, let's test it with a demo

After execution, the printed result is as follows, you can see from this, All threads of the current process are printed out, but only simple stack information is printed here, which has played a monitoring role for developers;

As a tool for tuning and finding errors It can be said that jstack is the most used tool, but due to limitations, it has been slowly replaced; everyone prefers to use the tool arthas developed by Alibaba; interested children can learn more!