美女程序媛发福利,读懂ANR的trace文件So easy

Bugly支持ANR上报后,很多童鞋反馈看不懂上报上来的trace文件,精神哥很担忧,因为读懂trace文件是分析ANR问题的最关键的一步。Trace文件是个什么鬼?App的进程发生ANR时,系统让活跃的Top进程都进行了一下dump,进程中的各种Thread就都dump到这个trace文件里了,所以trace文件中包含了每一条线程的运行时状态。刚好我们的美女攻城狮sunny(邹灵灵)最近收集了这块的内容,下面给大家详细介绍Thread Dump到底是个什么鬼,相信看完的童鞋,读懂trace文件就So easy了!

一、java线程的状态转换介绍

1.1新建状态(New)

用new语句创建的线程处于新建状态,此时它和其他Java对象一样,仅仅在堆区中被分配了内存。

1.2就绪状态(Runnable)

当一个线程对象创建后,其他线程调用它的start()方法,该线程就进入就绪状态,Java虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得CPU的使用权。

1.3运行状态(Running)

处于这个状态的线程占用CPU,执行程序代码。只有处于就绪状态的线程才有机会转到运行状态。

1.4阻塞状态(Blocked)

阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU。直到线程重新进入就绪状态,它才有机会转到运行状态。

阻塞状态可分为以下3种:

1)位于对象等待池中的阻塞状态(Blocked in object’s wait pool):当线程处于运行状态时,如果执行了某个对象的wait()方法,Java虚拟机就会把线程放到这个对象的等待池中,这涉及到“线程通信”的内容。

2)位于对象锁池中的阻塞状态(Blocked in object’s lock pool):当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他线程占用,Java虚拟机就会把这个线程放到这个对象的锁池中,这涉及到“线程同步”的内容。

3)其他阻塞状态(Otherwise Blocked):当前线程执行了sleep()方法,或者调用了其他线程的join()方法,或者发出了I/O请求时,就会进入这个状态。

1.5死亡状态(Dead)

当线程退出run()方法时,就进入死亡状态,该线程结束生命周期。

二、Thread Dump分析

2.1首先介绍一下Thread Dump信息的各个部分

线程info信息块:

1. "Timer-0" daemon prio=10tid=0xac190c00 nid=0xaef in Object.wait() [0xae77d000]2. java.lang.Thread.State: TIMED_WAITING (on object monitor)3. atjava.lang.Object.wait(Native Method)4. -waiting on <0xb3885f60> (a java.util.TaskQueue) ###继续wait5. atjava.util.TimerThread.mainLoop(Timer.java:509)6. -locked <0xb3885f60> (a java.util.TaskQueue) ###已经locked7. atjava.util.TimerThread.run(Timer.java:462)

* 线程名称:Timer-0

* 线程类型:daemon

* 优先级:10,默认是5

* jvm线程id:tid=0xac190c00,jvm内部线程的唯一标识(一般通过java.lang.Thread.getId()获取,通常用自增方式实现。)

* 对应系统线程id(Native Thread ID):nid=0xaef,和top命令查看的线程pid对应,不过一个是10进制,一个是16进制。(可以通过命令:top -H -p pid,查看该进程的所有线程信息)

* 线程状态:in Object.wait().

* 起始栈地址:[0xae77d000]

* Java thread statck trace:上面2~7行的信息。到目前为止这是最重要的数据,Java stack trace提供了大部分信息来精确定位问题根源。

对于thread dump信息,主要关注的是线程的状态和其执行堆栈。现在针对这两个重点部分进行讲解.

1、Java thread statck trace详解

堆栈信息应该逆向解读:程序先执行的是第7行,然后是第6行,依次类推。

– locked <0xb3885f60> (a java.util.ArrayList)- waiting on <0xb3885f60> (a java.util.ArrayList)

也就是说对象先上锁,锁住对象0xb3885f60,然后释放该对象锁,进入waiting状态。

为啥会出现这样的情况呢?看看下面的java代码示例,就会明白:

synchronized(obj) {………obj.wait();………}

在堆栈的第一行信息中,进一步标明了线程在代码级的状态,例如:

java.lang.Thread.State: TIMED_WAITING (parking)

解释如下:

|blocked|This thread tried to enter asynchronized block, but the lock was taken by another thread. This thread isblocked until the lock gets released.|blocked (on thin lock)|This is the same state asblocked, but the lock in question is a thin lock.|waiting|This thread calledObject.wait() on an object. The thread will remain there until some otherthread sends a notification to that object.|sleeping|This thread calledjava.lang.Thread.sleep().|parked|This thread calledjava.util.concurrent.locks.LockSupport.park().|suspended|The thread’s execution wassuspended by java.lang.Thread.suspend() or a JVMTI agent call.一只小狗在沙漠中旅行,找到了电线杆,结果还是憋死了,

美女程序媛发福利,读懂ANR的trace文件So easy

相关文章:

你感兴趣的文章:

标签云: