利用shell命令和浏览器优化jstack的结果显示

2 篇文章 0 订阅
jstack现状

当我们用jstack排查线程栈问题的时候,我们经常会遇到许多相同的线程栈,尤其是当我们使用了线程池或者系统框架使用了线程池的时候,许多重复的栈桢充满着整个屏幕,想要找到我们需要的信息比较麻烦
执行:

jstack 12321

结果:

"qtp837692250-110" #110 prio=5 os_prio=31 tid=0x00007fdc80c4d000 nid=0x7703 waiting on condition [0x0000700006d13000]
   java.lang.Thread.State: TIMED_WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c1fa59a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
	at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:517)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:563)
	at java.lang.Thread.run(Thread.java:748)

"qtp837692250-109" #109 prio=5 os_prio=31 tid=0x00007fdc812c6000 nid=0x7603 waiting on condition [0x0000700006c10000]
   java.lang.Thread.State: TIMED_WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c1fa59a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
	at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:337)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:517)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:39)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:563)
	at java.lang.Thread.run(Thread.java:748)
"Druid-ConnectionPool-Create-927542454" #41 daemon prio=5 os_prio=31 tid=0x00007fdc7e995000 nid=0x620f waiting on condition [0x00007000056d1000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c173cf10> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2443)

"Abandoned connection cleanup thread" #37 daemon prio=5 os_prio=31 tid=0x00007fdc7e992800 nid=0x9c03 in Object.wait() [0x00007000055ce000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
	- locked <0x00000006c131aa90> (a java.lang.ref.ReferenceQueue$Lock)
	at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43)

"container-0" #36 prio=5 os_prio=31 tid=0x00007fdc7e992000 nid=0x1207 waiting on condition [0x00007000054cb000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at org.apache.catalina.core.StandardServer.await(StandardServer.java:408)
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer$1.run(TomcatWebServer.java:181)

"ContainerBackgroundProcessor[StandardEngine[Tomcat]]" #35 daemon prio=5 os_prio=31 tid=0x00007fdc7e990800 nid=0x100f waiting on condition [0x00007000053c8000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1365)
	at java.lang.Thread.run(Thread.java:748)
awk优化

许多时候我们的系统都是跑在linux下面,于是我们可以通过linux的awk命令来把这些栈桢数据“合并”一下,然后用浏览器来查看
执行:

jstack 12321| awk '{total=NR;line[NR]=$0;}END{for(i=total;i>0;i--)print line[i];}'|awk '{
    gsub("<", "[", $0);
    gsub(">", "]", $0);
    if($0=="")
        str=""; 
    else{
        if(single[str"\r\n"$0]==""){
            son[str]=son[str]"##"str"\r\n"$0; 
            single[str"\r\n"$0]="n"; 
        } 
        str=str"\r\n"$0; 
    }
    leaf[str]++; 
    name[str]=$0; 
} END {
    stack[0]=""; 
    for(;;){
        if(length(stack) == 0) break; 
        s=stack[length(stack)-1]; 
        delete stack[length(stack)-1]; 
        if(s=="/") {
            print "</frame>";
            continue;
        } 
        print "<frame info='\''"name[s]"'\'' cnt='\''"leaf[s]"'\''>"; 
        stack[length(stack)]="/";
        if(son[s] != ""){
            split(son[s], arr, "##"); 
            for(i=length(arr);i>=0;i--){
                for(j=i-1;j>=0;j--){
                    if(leaf[arr[j]]<leaf[arr[i]]||((leaf[arr[j]]==leaf[arr[i]])&&(length(arr[j])>length(arr[i])))){
                        temp=arr[j];
                        arr[j]=arr[i];
                        arr[i]=temp;
                    }
                }
            };
            for(i=length(arr);i>=0;i--){
                if(arr[i] != "") 
                    stack[length(stack)]=arr[i]; 
            }
        }
    }
}' > /tmp/12321.xml

然后我们用浏览器打开/tmp/12321.xml文件
在这里插入图片描述
是不是清晰很多呢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值