jvm-栈-监控 02

jstack  监控  jvm

1、查看java 运行项目的ip

[root@demo]# ps -ef |grep java
root 1521 1334 99 11:35 pts/0 07:53:06 java -Xms32M -Xmx32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ -jar gift-0.0.1-SNAPSHOT-obf.jar
root 2454 1550 0 16:27 pts/1 00:00:00 grep --color=auto java
You have new mail in /var/spool/mail/root

2、查看jstack pid ,

[root@demo]# jstack 1521

打印很多信息,复制其中一段栈信息,包含的信息

"http-nio-18089-BlockPoller" #17 daemon prio=5 os_prio=0 tid=0x00007fd4c0f36800 nid=0x604 runnable [0x00007fd490ca5000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000fed51cc0> (a sun.nio.ch.Util$3)
- locked <0x00000000fed51cb0> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000fed51b88> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:331)

3、查看栈包含的信息以及含义

 http-nio-18089-BlockPoller -线程名称

#17 -编号

daemon --线程类型,是守护线程

prio=5 --线程优先级

os_prio=0 --系统优先级

tid=0x00007fd4c0f3680   -JVM内部线程的唯一标识

nid=0x604 - netv id 线程对应的本地线程id号,本地线程才是真实的线程实体

runnable -本地线程状态

 [0x00007fd490ca5000]--线程占用的内存地址

 

4、JVM 线程运行的状态,JVM thread status 有如下五个: 

在 Java 中,线程的状态可以通过 Thread.State 枚举类来表示,也可以通过 jstack 等工具查看线程转储(thread dump)中的状态。以下是 JVM 线程的主要状态及其含义:

 New  Runnable Blocked WaiTing Time_Waiting Terminated

1. NEW (新建)

  • 线程刚被创建,但尚未调用 start() 方法

  • 此时线程还未开始执行

2. RUNNABLE (可运行)

  • 线程正在 JVM 中执行,或准备就绪等待操作系统分配 CPU 资源

  • 包括两种子状态:

    • Ready:等待 CPU 时间片

    • Running:正在 CPU 上执行

对应的线程样子:java.lang.Thread.State: RUNNABLE

3. BLOCKED (阻塞)

  • 线程被阻塞,等待获取监视器锁(monitor lock)

  • 通常发生在进入 synchronized 方法/代码块时,锁已被其他线程持有

  • 在 jstack 输出中显示为 "BLOCKED (on object monitor)"

java.lang.Thread.State: BLOCKED (on object monitor)

4. WAITING (无限期等待)

  • 线程主动进入等待状态,直到被其他线程显式唤醒

  • 常见场景:

    • Object.wait() (未设置超时)

    • Thread.join() (未设置超时)

    • LockSupport.park()

  • 在 jstack 中通常显示为 "WAITING (on object monitor)" 或 "WAITING (parking)"

java.lang.Thread.State: WAITING (parking):一直等某个条件发生

java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定时的,某个条件不到来,也将定时唤醒自己

5. TIMED_WAITING (限期等待)

  • 线程进入有时间限制的等待状态

  • 常见场景:

    • Thread.sleep(long)

    • Object.wait(long)

    • Thread.join(long)

    • LockSupport.parkNanos()

    • LockSupport.parkUntil()

  • 在 jstack 中显示为 "TIMED_WAITING (sleeping)" 或 "TIMED_WAITING (on object monitor)"

6. TERMINATED (终止)

  • 线程已完成执行,或者因异常而终止

线程状态转换图

 

 

 死锁(Deadlock)示例

重点关注中间四种状态 blocke,runable,waiting,time_waiting

 

 blocked状态与waiting状态的区别

1. 基本定义区别

状态BLOCKED (阻塞)WAITING (等待)
触发方式 被动阻塞,由JVM自动设置 主动等待,由程序显式调用方法触发
恢复方式 当获取到监视器锁时自动恢复 必须由其他线程显式唤醒(notify/interrupt)

  

栈中,锁的信息

线程堆栈(jstack 或 Thread Dump)中的锁信息

示例 1:BLOCKED 状态的线程

"Thread-1" #12 prio=5 os_prio=0 tid=0x00007f487c0b8000 nid=0x4e1 waiting for monitor entry [0x00007f487a7e7000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.example.LockDemo.syncMethod(LockDemo.java:10)
        - waiting to lock <0x000000076bf0b0d0> (a com.example.LockDemo)  // 锁对象的地址

关键信息:

  • waiting for monitor entry:线程因竞争锁失败进入 BLOCKED 状态。

  • waiting to lock <0x000000076bf0b0d0>:被阻塞的锁对象的内存地址(可用于关联其他线程的持有者)

示例 2:持有锁的线程

"Thread-0" #11 prio=5 os_prio=0 tid=0x00007f487c0b6000 nid=0x4e0 runnable [0x00007f487a8e8000]
   java.lang.Thread.State: RUNNABLE
        at com.example.LockDemo.syncMethod(LockDemo.java:8)
        - locked <0x000000076bf0b0d0> (a com.example.LockDemo)  // 当前线程持有的锁
  • 关键信息:

    • locked <0x000000076bf0b0d0>:线程当前持有的锁对象地址(与 Thread-1 等待的是同一个锁)。

 

 

----------------------------

arthas

1、先启动一个java 项目,查看pid

[root@demo]# nohup java -jar test.jar &
[1] 3051
[root@demo]# nohup: ignoring input and appending output to ‘nohup.out’

[root@demo]# ps -ef |grep java
root 3051 1334 49 19:56 pts/0 00:00:10 java -jar test.jar
root 3075 1334 0 19:57 pts/0 00:00:00 grep --color=auto java
 pid是3051 

2、下载arthas-boot.jar  使用arthas 查看, 可以看到运行的test.jar 项目,如果启动多个项目则下面展示多个。

[root@demo]# java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.4.5
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 3051 test.jar
1 ---输入1
[INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/4.0.5?mirror=aliyun
[INFO] Download arthas success.
[INFO] arthas home: /root/.arthas/lib/4.0.5/arthas
[INFO] Try to attach process 3051
[INFO] Attach process 3051 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'

wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 4.0.5
main_class test.jar
pid 3051
start_time 2025-05-29 19:56:44.319
currnt_time 2025-05-29 20:03:12.476

[arthas@3051]$   ---已进入arthas 

看到以上信息,就代表arthas 监控这个进程ok

 

---arthas常用命令:trace、thread、dashboard

3、接下来就进入到了arthas 进程,就可以输入help 去查看

[arthas@3051]$ help  显示很多信息

[arthas@3051]$ help

 NAME         DESCRIPTION                                                                            

 help         Display Arthas Help                                                                    

 auth         Authenticates the current session                                                      

 keymap       Display all the available keymap for the specified connection.                         

 sc           Search all the classes loaded by JVM                                                   

 sm           Search the method of classes loaded by JVM                                             

 classloader  Show classloader info                                                                  

 jad          Decompile class                                                                        

 getstatic    Show the static field of a class                                                       

 monitor      Monitor method execution statistics, e.g. total/success/failure count, average rt, fai

              l rate, etc.                                                                           

 stack        Display the stack trace for the specified class and method                             

 thread       Display thread info, thread stack                                                      

 trace        Trace the execution time of specified method invocation.                               

 watch        Display the input/output parameter, return object, and thrown exception of specified m

              ethod invocation                                                                       

 tt           Time Tunnel                                                                            

 jvm          Display the target JVM information                                                     

 memory       Display jvm memory info.                                                               

 perfcounter  Display the perf counter information.                                                  

 ognl         Execute ognl expression.                                                               

 mc           Memory compiler, compiles java files into bytecode and class files in memory.          

 redefine     Redefine classes. @see Instrumentation#redefineClasses(ClassDefinition...)             

 retransform  Retransform classes. @see Instrumentation#retransformClasses(Class...)                 

 dashboard    Overview of target jvm's thread, memory, gc, vm, tomcat info.                          

 dump         Dump class byte array from JVM                                                         

 heapdump     Heap dump                                                                              

 options      View and change various Arthas options                                                 

 cls          Clear the screen                                                                       

 reset        Reset all the enhanced classes                                                         

 version      Display Arthas version                                                                 

 session      Display current session information                                                    

 sysprop      Display and change the system properties.                                              

 sysenv       Display the system env.                                                                

 vmoption     Display, and update the vm diagnostic options.                                         

 logger       Print logger info, and update the logger level                                         

 history      Display command history                                                                

 cat          Concatenate and print files                                                            

 base64       Encode and decode using Base64 representation                                          

 echo         write arguments to the standard output                                                 

 pwd          Return working directory name                                                          

 mbean        Display the mbean information                                                          

 grep         grep command for pipes.                                                                

 tee          tee command for pipes.                                                                 

 profiler     Async Profiler. https://github.com/jvm-profiling-tools/async-profiler                  

 vmtool       jvm tool                                                                               

 stop         Stop/Shutdown Arthas server and exit the console.      

4、如果要某个命令操作   ,比如 trace                 

[arthas@3051]$ trace -h   ---就会出来这个命令的用法

5、退出arthas 有两个命令,一个是stop,一个是quit

quit  不会关闭arthas服务

stop 会关闭服务

演示:

[arthas@3051]$ quit  ------退出服务
Session has been terminated.
Arthas is still running in the background.
To completely shutdown arthas, please execute the 'stop' command.
You have new mail in /var/spool/mail/root
[root@demo]# netstat -lntp |grep 3658          ---  从上面([INFO] Attach process  3051success.[INFO] arthas-client connect 127.0.0.1 3658)可以看到这个服务有这个端口,可以检查看以是否还存在

tcp6 0 0 127.0.0.1:3658 :::* LISTEN 3051/java       --可以看到服务还存在
[root@demo]#

6、重新进入arthas 服务,查看dashboard,

[root@demo]# java -jar arthas-boot.jar

[arthas@3051]$ dashboard ------显示当前系统的实时数据面板

 

7、使用 thread 

Arthas thread 命令参数对照表

命令格式功能说明示例/备注
thread 查看所有线程信息(ID、状态、CPU占用等) 默认按CPU使用率排序
thread -n 3 显示最繁忙的3个线程(CPU占用最高) -n 参数指定显示数量
thread <id> 查看指定线程的详细堆栈信息 id 为 thread 命令输出的第一列
thread -b 快速定位阻塞(BLOCKED)线程 等价于 thread --state BLOCKED
thread --state BLOCKED 查看所有处于阻塞状态的线程 支持其他状态:RUNNABLEWAITING
thread | grep "xxx" 过滤线程信息(按关键字) 如:thread | grep "http-nio"
thread | grep BLOCKED 过滤所有阻塞线程(与 -b 效果相同) 等价于 thread --state BLOCKED

使用场景示例

场景命令目的
定位CPU飙升问题 thread -n 3 找出最消耗CPU的线程
分析死锁 thread -b 快速查看阻塞线程的锁竞争
监控线程池状态 thread | grep "pool-" 过滤线程池相关线程
检查I/O等待 thread --state TIMED_WAITING 查看因超时等待(如网络IO)的线程

 

示例1:查看 thread --state BLOCKED

[arthas@1456]$ thread --state BLOCKED
Threads Total: 22, NEW: 0, RUNNABLE: 11, BLOCKED: 2, WAITING: 5, TIMED_WAITING: 4, TERMINATED: 0
ID NAME GROUP PRIORITY STATE %CPU DELTA_TI TIME INTERRUP DAEMON
16 线程2 main 5 BLOCKED 0.02 0.000 0:0.014 false false
15 线程1 main 5 BLOCKED 0.01 0.000 0:0.014 false false

8、使用trace 

trace 是 Arthas 中非常强大的性能分析命令,用于追踪方法内部调用路径,并统计每个节点的耗时情况

查看帮助 :trace -h

基本语法: trace [全限定类名] [方法名] [参数选项]

常用场景和示例

场景1:追踪方法调用链耗时

[arthas@3051]$ trace com.gift.controller.OrderController findByOrderNumber

  • 作用:追踪findByOrderNumber方法的完整调用链,显示每个调用节点的耗时

  • 输出:会显示方法调用的树形结构,包含每个节点的耗时(ms)

场景2:限制追踪次数

[arthas@3051]$ trace com.gift.controller.OrderController findByOrderNumber -n 2

  • -n 2:只捕捉2次请求的追踪信息

  • 适用场景:在高流量环境下,避免产生过多日志

场景3:按耗时筛选

[arthas@3051]$  trace com.gift.controller.OrderController findByOrderNumber '#cost>1000'

  • #cost>1000:只显示耗时超过1000ms的调用

  • 适用场景:快速定位性能瓶颈

场景4:深入追踪耗时方法

如果发现某个被调用的方法耗时较长,可以继续追踪该方法

trace com.gift.service.impl.OrderServiceImpl queryOrderDetail

  • 方法论:从外层到内层逐步深入追踪,定位最终的性能瓶颈

高级用法

1. 追踪重载方法

trace com.example.Class *methodName params.length==2
  • 可以指定参数个数或类型来区分重载方法

2. 排除特定调用

trace com.example.Class methodName -E "java.lang.Thread|java.util.concurrent"
  • -E 参数用于排除不想看到的调用路径

3. 观察调用上下文

trace com.example.Class methodName -v
  • -v 参数可以打印更详细的调用信息

适用场景

  1. 定位接口性能瓶颈:快速发现接口中哪个方法调用耗时最长

  2. 分析复杂调用链:理清多层嵌套调用的性能分布

  3. 优化前后对比:在优化前后分别trace,验证优化效果

  4. 生产环境诊断:无需修改代码或重启服务,实时分析性能问题

 

posted @ 2025-05-29 20:42  Shafir莎菲尔  阅读(31)  评论(0)    收藏  举报