V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
esolve
V2EX  ›  问与答

jstack 显示的线程是出问题的线程还是所有的线程?

  •  
  •   esolve · 2017-11-15 19:04:52 +08:00 · 1406 次点击
    这是一个创建于 2371 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果是所有的线程

    那对于正常的线程来说

    那那些 at 代表啥?

    如果是出问题的线程

    有的线程状态是 running,有啥问题?

    8 条回复    2017-11-16 18:31:28 +08:00
    kaneg
        1
    kaneg  
       2017-11-15 20:28:32 +08:00 via iPhone
    所有的。
    at 是每个线程当前正在执行方法的堆栈信息
    esolve
        2
    esolve  
    OP
       2017-11-15 23:16:30 +08:00
    @kaneg 一个线程里面的代码分支很多,at 只是其中的一条,为何只显示其中一条?是这条出问题了吗?
    kaneg
        3
    kaneg  
       2017-11-16 07:06:25 +08:00 via iPhone
    @esolve 是 jstack 运行的那个时候,线程执行到的那个分支
    esolve
        4
    esolve  
    OP
       2017-11-16 11:10:57 +08:00
    @kaneg 那如何定位问题啊

    譬如一个 http 线程耗时很长甚至不成功,
    要排查原因
    那怎么找到问题?


    假设线程有好几个数据库查询语句,
    有一个语句耗时很长甚至不成功
    我想找到这个语句

    你的意思 jstack 是快照,
    那么我用 jstack 的时候,这个线程恰好运行到没啥问题的其他几个数据库查询
    而不是我要找的那个数据库查询
    这样怎么找问题所在?
    kaneg
        5
    kaneg  
       2017-11-16 11:28:18 +08:00
    @esolve

    这种动态的情况用快照这种方法就不一定管用了。一般来说就是打 log,在可能执行到的地方都打上 log,与耗时相关的打上时间,然后在 log 中定位你认为有问题的行,这样逐渐缩小范围,定位到可能出问题的代码行,然后再用 Remote Debug,打好合适的断点,逐行排除,直至找到问题原因。
    esolve
        6
    esolve  
    OP
       2017-11-16 13:23:35 +08:00
    @kaneg 有点奇怪,只能快照的话,感觉 jstack 根本找不出问题啊,除非是线程长时间的阻塞。

    BTW: 我看到的一个问题是:

    java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:100)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:143)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:173)
    - locked <0x000000056ce28410> (a com.mysql.jdbc.util.ReadAheadInputStream)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2911)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3337)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3327)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2530)
    - locked <0x000000056ca3a818> (a com.mysql.jdbc.JDBC4Connection)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1907)
    - locked <0x000000056ca3a818> (a com.mysql.jdbc.JDBC4Connection)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2030)
    - locked <0x000000056ca3a818> (a com.mysql.jdbc.JDBC4Connection)

    这里有几个 locked
    这是啥意思? 过程中阻塞了四次?每次一定秒数?
    kaneg
        7
    kaneg  
       2017-11-16 15:15:15 +08:00
    @esolve
    这里的 locked 是同步锁,在 java 的多线程代码中很常见,没有什么不正常的。
    从下面的行可以看出
    java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)

    你的代码在进行持续的 Read 操作,而从下面的 Sql connection 可以推断出,当前线程在执行完一个 sql 后在往回读 Result。

    如果这个时间很长,一般有两种原因:

    1. 网络速度慢
    2. sql 执行后的结果数据量很大
    esolve
        8
    esolve  
    OP
       2017-11-16 18:31:28 +08:00
    @kaneg 这上面这些 at 和抛异常的 at 有啥区别
    异常里的每一个 at 都是一个函数调用入口,一步一步直到抛出异常的那行
    这里的每个 at 代表啥?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1075 人在线   最高记录 6547   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 19:09 · PVG 03:09 · LAX 12:09 · JFK 15:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.