• jstack命令的使用


    文章来源:https://blog.csdn.net/wufaliang003/article/details/80414267

    jstack是java虚拟机自带的一种堆栈跟踪工具。

    jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,

    如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者

    等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程

    序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung

    的状态,jstack是非常有用的。

    jstack命令:

    Usage:
        jstack [-l] <pid>
            (to connect to running process)
        jstack -F [-m] [-l] <pid>
            (to connect to a hung process)
        jstack [-m] [-l] <executable> <core>
            (to connect to a core file)
        jstack [-m] [-l] [server_id@]<remote server IP or hostname>
            (to connect to a remote debug server)
    
    Options:
        -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
        -m  to print both java and native frames (mixed mode)
        -l  long listing. Prints additional information about locks
        -h or -help to print this help message

    -F 当’jstack [-l] pid’没有相应的时候强制打印栈信息,如果直接jstack无响应时,用于强制jstack,一般情况不需要使用

    -l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得长久得多

    (可能会差很多倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用

    -m 打印java和native c/c++ 框架的所有栈信息.可以打印JVM的堆栈,显示上Native的栈帧,一般应用排查不需要使用

     执行命令:

     jstack -m 12905
    Attaching to process ID 12905, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 24.71-b01
    Deadlock Detection:
    
    No deadlocks found.
    
    ----------------- 12908 -----------------
    0x000000358d40b63c __pthread_cond_wait + 0xcc
    0x00007fcad07875a5 Unsafe_Park + 0x125
    0x00007fcacc4b17f8 * sun.misc.Unsafe.park(boolean, long) bci:0 (Interpreted frame)
    0x00007fcacc4a5058 * java.util.concurrent.locks.LockSupport.park(java.lang.Object) bci:14 line:186 (Interpreted frame)
    0x00007fcacc4a5058 * java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt() bci:1 line:834 (Interpreted frame)
    0x00007fcacc4a5350 * java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(int) bci:72 line:994 (Interpreted frame)
    0x00007fcacc4a5058 * java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(int) bci:24 line:1303 (Interpreted frame)

    线程状态

    想要通过jstack命令来分析线程的情况的话,首先要知道线程都有哪些状态,下面这些状态是我们使用jstack命令查看线程堆栈信息时可能会看到的线程的几种状态:

    NEW,未启动的。不会出现在Dump中。
    
    RUNNABLE,在虚拟机内执行的。
    
    BLOCKED,受阻塞并等待监视器锁。
    
    WATING,无限期等待另一个线程执行特定操作。
    
    TIMED_WATING,有时限的等待另一个线程的特定操作。
    
    TERMINATED,已退出的。

    Monitor

    在多线程的 JAVA程序中,实现线程之间的同步,就要说说 Monitor。 Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,
    也仅有一个 monitor。下 面这个图,描述了线程和 Monitor之间关系,以 及线程的状态转换图:

    进入区(Entrt Set):表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则迚入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。

    拥有者(The Owner):表示某一线程成功竞争到对象锁。

    等待区(Wait Set):表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。

    从图中可以看出,一个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”

    和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()”

    先看 “Entry Set”里面的线程。我们称被 synchronized保护起来的代码段为临界区。当一个线程申请进入临界区时,它就进入了 “Entry Set”队列。

  • 相关阅读:
    <HTTP>ASI实现的注册方法:利用http的get和post两种方式
    <Ruby>社区服务端启动流程
    <iOS>ASIHTTPRequest和ASIDownloadCache实现本地缓存
    <iOS>关于Xcode上的Other linker flags
    <HTTP>ASI实现的登陆方法
    【pool drain】和【pool release】区别
    <UI>TableViewCELL长按事件
    <UI>UIView的autoresizingMask属性
    <UI>自定义UITableView的右侧索引
    <cocos2D>ccLabel相关
  • 原文地址:https://www.cnblogs.com/taiguyiba/p/9470861.html
Copyright © 2020-2023  润新知