美文网首页Java 虚拟机程序员
【Java 虚拟机笔记】jstack 堆栈跟踪工具相关整理

【Java 虚拟机笔记】jstack 堆栈跟踪工具相关整理

作者: 58bc06151329 | 来源:发表于2019-03-04 13:27 被阅读41次

    文前说明

    作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

    本文仅供学习交流使用,侵权必删。
    不用于商业目的,转载请注明出处。

    1. 堆栈跟踪工具(Stack Trace for Java)

    • jstack 命令用于生成虚拟机当前时刻的线程快照(一般称为 threaddump 或者 javacore 文件)。
      • 线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
      • 可以通过 -J 方式,将虚拟机参数传递给 jstack 调用的启动程序。例如 -J-Xms48m。
      • 如果给定进程是在 64 位虚拟机上运行,那么需要指定参数 -J-d64

    1.1 命令格式

    • jstack [ option ] pid
    • jstack [ option ] executable core
    • jstack [ option ] [server-id@]remote-hostname-or-IP
      • options 是选项相互排斥。选项(如果使用)应紧跟在命令名之后。
      • pid 是需要打印配置信息的进程的 ID。这个进程必须是一个 Java 进程。为了获得在机器上运行的 Java 进程的列表可以使用 jps 命令。
      • executable 是产生核心堆的 Java 可执行文件。
      • core 是需要打印配置信息的核心文件。
      • remote-hostname-or-IP 是远程调试服务器的主机名或 IP 地址。
        • 不指定的情况下运行 jstack,将在本地主机上查找虚拟机进程。
      • server-id 如果在同一远程主机上运行多个调试服务器,则为可选的唯一 ID。
    选项 说明
    -F 强制。 使用 jstack [-l] pid 无响应时可以强制执行。
    -l 长清单,打印有关锁的其他信息。http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/AbstractOwnableSynchronizer.html
    -m 打印混合模式(Java 和 native C/C++)堆栈跟踪。
    -h 打印帮助信息。
    -help 打印帮助信息。

    1.2 执行样例

    [root@localhost ~]# sudo -u ovirt jstack -l 1638
    2019-02-23 04:02:51
    Full thread dump OpenJDK 64-Bit Server VM (24.161-b00 mixed mode):
    
    "process reaper" daemon prio=10 tid=0x00007fe2900cb800 nid=0x30b8 waiting on condition [0x00007fe26c74d000]
       java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000cd765128> (a java.util.concurrent.SynchronousQueue$TransferStack)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
        at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
        at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
        at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1075)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
        at java.lang.Thread.run(Thread.java:748)
    
       Locked ownable synchronizers:
        - None
    
    "Attach Listener" daemon prio=10 tid=0x00007fe2900cb000 nid=0x2cb7 waiting on condition [0x0000000000000000]
       java.lang.Thread.State: RUNNABLE
    
       Locked ownable synchronizers:
        - None
    
    "ajp-/127.0.0.1:8702-11" daemon prio=10 tid=0x00007fe278308800 nid=0x7e1 in Object.wait() [0x00007fe26bea2000]
       java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:503)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:881)
        - locked <0x00000000d0102e68> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:907)
        at java.lang.Thread.run(Thread.java:748)
    
       Locked ownable synchronizers:
        - None
    
    "ajp-/127.0.0.1:8702-10" daemon prio=10 tid=0x00007fe2783cf000 nid=0x7da runnable [0x00007fe26bfa3000]
       java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:153)
        at java.net.SocketInputStream.read(SocketInputStream.java:122)
        at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:1124)
        at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:1206)
        at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:438)
        at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:420)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926)
        at java.lang.Thread.run(Thread.java:748)
    

    1.3 输出格式

    信息 说明
    prio 线程的优先级
    tid 线程 ID
    nid 操作系统映射的线程 ID,(例如:nid=0x75a)
    0x00007fcd86af2000 表示线程栈的起始地址。
    0x00000000c709e5c0 锁的对象的 ID

    发现死锁现象

    Found one Java-level deadlock:
    =============================
    "Thread-1":
    waiting to lock monitor 0x0003f334 (object 0x22c19f18, a java.lang.Object),
    which is held by "Thread-0"
    "Thread-0":
    waiting to lock monitor 0x0003f314 (object 0x22c19f20, a java.lang.Object),
    which is held by "Thread-1"
    

    相关文章

      网友评论

        本文标题:【Java 虚拟机笔记】jstack 堆栈跟踪工具相关整理

        本文链接:https://www.haomeiwen.com/subject/ewmbuqtx.html