参考:Java线程Dump分析工具–jstack
dump 文件里,值得关注的线程状态有:
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞,Blocked(重点关注)
停止,Parked
先在cmd导出trace.txt文件:
adb pull /data/anr/traces.txt
ANR的 trace.txt 如下:
----- pid 12909 at 2018-07-12 18:15:29 -----
Cmd line: com.dch.dai
Build fingerprint: 'Xiaomi/chiron/chiron:8.0.0/OPR1.170623.027/8.2.1:user/release-keys'
ABI: 'arm64'
Build type: optimized
Zygote loaded classes=4895 post zygote classes=1815
Intern table: 75547 strong; 134 weak
JNI: CheckJNI is on; globals=816 (plus 67 weak)
Libraries: /system/app/WebViewGoogle/WebViewGoogle.apk!/lib/arm64-v8a/libwebviewchromium.so /system/lib64/libandroid.so /system/lib64/libcompiler_rt.so /system/lib64/libjavacrypto.so /system/lib64/libjnigraphics.so /system/lib64/libmedia_jni.so /system/lib64/libmiuiclassproxy.so /system/lib64/libmiuinative.so /system/lib64/libqti_performance.so /system/lib64/libsoundpool.so /system/lib64/libwebviewchromium_loader.so /system/lib64/libwebviewchromium_plat_support.so libjavacore.so libopenjdk.so (14)
/data/app/com.dch.dai-N54RdMqTyLjfusMZSC1tgQ==/oat/arm64/base.odex: quicken
/data/dalvik-cache/arm64/system@app@[email protected]@classes.dex: speed
/system/framework/oat/arm64/gson.odex: quicken
/system/framework/oat/arm64/volley.odex: quicken
/data/dalvik-cache/arm64/system@app@[email protected]@classes.dex: speed
Current JIT code cache size: 998KB
Current JIT data cache size: 597KB
Current JIT capacity: 2MB
Current number of JIT code cache entries: 1912
Total number of JIT compilations: 2053
Total number of JIT compilations for on stack replacement: 2
Total number of JIT code cache collections: 9
Memory used for stack maps: Avg: 183B Max: 19KB Min: 24B
Memory used for compiled code: Avg: 505B Max: 41KB Min: 4B
Memory used for profiling info: Avg: 134B Max: 5KB Min: 32B
Start Dumping histograms for 2065 iterations for JIT timings
Compiling: Sum: 2.584s 99% C.I. 0.024ms-14.751ms Avg: 1.257ms Max: 53.463ms
TrimMaps: Sum: 122.034ms 99% C.I. 5us-617.999us Avg: 59.355us Max: 1861us
Code cache collection: Sum: 9.911ms 99% C.I. 0.311ms-5.015ms Avg: 1.101ms Max: 5.182ms
Done Dumping histograms
Memory used for compilation: Avg: 126KB Max: 8MB Min: 21KB
ProfileSaver total_bytes_written=11503
ProfileSaver total_number_of_writes=1
ProfileSaver total_number_of_code_cache_queries=1
ProfileSaver total_number_of_skipped_writes=0
ProfileSaver total_number_of_failed_writes=0
ProfileSaver total_ms_of_sleep=41067
ProfileSaver total_ms_of_work=7
ProfileSaver max_number_profile_entries_cached=1
ProfileSaver total_number_of_hot_spikes=52
ProfileSaver total_number_of_wake_ups=39
suspend all histogram: Sum: 36.791ms 99% C.I. 1.391us-1505.279us Avg: 164.245us Max: 13683us
DALVIK THREADS (47):
"main" prio=5 tid=1 Runnable
| group="main" sCount=0 dsCount=0 flags=0 obj=0x763647d0 self=0x765e2bfa00
| sysTid=12909 nice=-4 cgrp=default sched=0/0 handle=0x7662b199b0
| state=R schedstat=( 0 0 0 ) utm=1960 stm=107 core=6 HZ=100
| stack=0x7ff8ec7000-0x7ff8ec9000 stackSize=8MB
| held mutexes= "mutator lock"(shared held)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1138)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager.setPageTransformer(ViewPager.java:712)
at com.dch.dai.fragment.home.FeaturedFragment.setTopBannerData(FeaturedFragment.java:521)
at com.dch.dai.fragment.home.FeaturedFragment.loadFeaturedData(FeaturedFragment.java:294)
at com.dch.dai.fragment.home.FeaturedFragment$2.onPostExecute(FeaturedFragment.java:256)
at com.dch.dai.utils.http.MyAsyncTask.onPostExecute(MyAsyncTask.java:38)
at com.dch.dai.utils.http.MyAsyncTask.onPostExecute(MyAsyncTask.java:9)
at android.os.AsyncTask.finish(AsyncTask.java:695)
at android.os.AsyncTask.-wrap1(AsyncTask.java:-1)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6665)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
.....省略
1、搜索[ Cmd line: ]查看进程,找到自己的APP
2、搜索 [ “main” prio ] 查看主线程,找到出问题的代码位置
3、分析原因:
原因:setCurrentItem时,主线程测量滑动距离,绘制UI阻塞
解决:把viewpager的item数量设置小一点即可
mViewPager.setCurrentItem(homeTopBannerData.size() * 100);
参考:ViewPager无限滑动
—– pid 19493 at 2017-12-06 15:37:40 —–
Cmd line: com.dch.loan
Build fingerprint: ‘HUAWEI/PIC-AL00/HWPIC:7.0/HUAWEIPIC-AL00/C00B173:user/release-keys’
发生ANR的进程id、时间和进程名称。
线程的基本信息:
其中 tll 、 tsl、 tscl 、ghl 、 hwl 、 hwll分别对应:
thread list lock,
thread suspend lock,
thread suspend count lock,
gc heap lock,
heap worker lock,
heap worker list lock。
“main” prio=5 tid=1 Native
线程名称、线程的优先级、线程锁id和线程状态。线程名称是启动线程的时候手动指明的,
这里的main标识是主线程,是Android自动设定的一个线程名称,如果是自己手动创建的线程,
一般会被命名成“Thread-xx”的格式,其中xx是线程id,它只增不减不会被复用;
注意这其中的tid不是线程的id,它是一个在Java虚拟机中用来实现线程锁的变量,随着线程的增减,这个变量的值是可能被复用的
group=”main” sCount=1 dsCount=0 obj=0x77020b18 self=0x78616a1a00
group是线程组名称。
sCount是此线程被挂起的次数,
dsCount是线程被调试器挂起的次数,
当一个进程被调试后,sCount会重置为0,调试完毕后sCount会根据是否被正常挂起增长,
但是dsCount不会被重置为0,所以dsCount也可以用来判断这个线程是否被调试过。
obj表示这个线程的Java对象的地址,
self表示这个线程本身的地址。
sysTid=19493 nice=-4 cgrp=default sched=1073741825/1 handle=0x78657cfa98
线程的调度信息
sysTid是Linux下的内核线程id,
nice是线程的调度优先级,
sched分别标志了线程的调度策略和优先级,
cgrp是调度属组,
handle是线程的处理函数地址。
state=S schedstat=( 9706803631 140093705 7027 ) utm=800 stm=170 core=4 HZ=100
“`
线程当前上下文信息
state是调度状态;
schedstat从/proc/[pid]/task/[tid]/schedstat读出,三个值分别表示线程在cpu上执行的时间、线程的等待时间和线程执行的时间片长度,
有的android内核版本不支持这项信息,得到的三个值都是0;
utm是线程用户态下使用的时间值(单位是jiffies);
stm是内核态下的调度时间值;
core是最后执行这个线程的cpu核的序号。
其他:线程的调用栈信息