androidtrace分析
㈠ Android ANR trace 報告怎麼看
後綴名是什麼是.txt嗎?Log分析你還可以去data/anr的目錄下把trace.txt這個文件拷貝出來,在該文件中會寫了產生anr的函數堆棧可以幫助分析
㈡ 如何分析android bugreport
一、ChkBugReport介紹
ChkBugReport是一個開源工具,它可以把你得到的bugreprot解析成適合閱讀的html文件。導出的html文件包含了根據bugreport數據得出的圖表和分析結論。
它的源碼中用到了以下開源類庫: jQuery ,jsTree jquery plugin , tablednd jQuery plugin , tablesorter jQuery plugin ,js-hotkeys, jquery-cookie 。學習輸出報告文檔型html可以參考源碼。
目前ChkBugReport可以從bugreport數據中抽取出如下信息:
1、Stacktraces ChkBugReport可以從bugreport中解析出輸出bugreport的最後時刻、導致ANR時刻甚至更多時刻的堆棧信息。在例子中你可以看到進程的優先順序和策略都已標示出來,堆棧中耗時的部分顏色是黑紅,一些違反Strict Mode的部分(比如主線程中使用資料庫)顏色標記為亮紅。如果這個線程死鎖,在報告的Errors將會出現。
2、Logs 這部分是對system、main和kernel日誌的分析,在這里你可以看到每個進程內存使用圖、那個程序產生的log最多、Activity的啟動耗時、資料庫操作耗時統計、對象被鎖定時間、AIDL調用時間、Activity和Service的生命周期及其在內存中使用頻率等等,詳見
3、Packages ChkBugReport解析bugreport中存儲的packages.xml並展示一系列的packages、user ids和 permissions。參見
4、Processes 操作app過程中產生的系統事件日誌、內存使用信息等等,參見
5、Battery statistics 電池使用統計信息,參見
6、CPU Frequency statistics CPU頻率統計信息,參見
7、Raw data 被分割成小段的原始數據
同時ChkBugReport也可以檢測到(潛在的)錯誤,這些錯誤在輸出的報告Errors部分中可以找到。你也可以在輸出報告的stacktrace中找到死鎖或一些違反Strict Mode的行為。
二、ChkBugReport使用
使用很簡單:1 java -jar $HOME/Downloads/chkbugreport.jar $HOME/tmp/bugreport.txt
你也可以把chkbugreport.jar加到path下,然後這樣使用1 chkbugreport thebugreport.txt
該工具將根據你的bugreport數據輸出一個分析結果目錄bugreport_out。
你可以使用如下命令取得bugreport:1 adb shell bugreport > bugreport.txt
當然你可以使用ChkBugReport分析bugreport的部分數據比如/data/anr/traces.txt1 chkbugreport -sl:the_system_log.txt -sa:traces.txt mmy
這將輸出分析結果到mmy_out。
你甚至可以使用ChkBugReport分析traceview生成的數據1 chkbugreport -t something.prof
Prof數據生成方法可以參考以下方法:
1、可以使用eclipse插件traceview生成
2、也可以按如下步驟:
a.用adb shell ps列出所有進程並找出你想要trace的進程的PID
b.執行adb shell am profile PID start /data/profile.dat,開始分析
c.操作你的app
d.執行adb shell am profile PID stop ,停止分析
e.導出數據並清除臨時文件:adb pull /data/profile.dat adb shell rm /data/profile.dat
f.使用ChkBugReport進行分析 chkbugreport -t profile.dat
㈢ 請教大牛怎麼分析ANR文件
對於Android ANR而言,ANR發生時mp的trace.log 非常關鍵,ANR應用的各個線程trace代表ANR發生那一瞬間各個線程的運行狀態,類似一個快照;如果你的應用因為主線程阻塞而發生ANR,通過主線程trace就可以很容易定位到阻塞點;
如果要有效通過trace分析ANR,首先第一點需要通過main.log確認是主線程阻塞或發生死循環導致的ANR,才能確認主線程的trace有參考價值,因為trace僅是某一瞬間的動作,如果主線程5秒阻塞,那這5秒內主線程的狀態都是一樣的,所以可以通過trace確認阻塞點;
以一下堆棧為例:
"main"位置欄位代表線程名,Android各個應用主線程都叫做"main",關鍵以sysTid=9816反映的這個數字區分是哪一個應用的主線程;
sysTid=表示系統中的線程號;
tid=表示本進程中線程排號;
Native位置欄位表示線程狀態,線程的狀態通常有Blocked,Waiting,Native,Runnable,SuSpend等等。通常Blocked,Waiting兩個狀態表示明顯阻塞,而Native,SuSpend可能是阻塞,需要具體問題具體分析,Runnable表示線程正常運行,沒有阻塞;
以下堆棧,反映ThreadedRenderer.nFence沒有響應ThreadedRenderer.fence調用,然後ThreadedRenderer.fence又沒有響應ViewRootImpl.performDraw,所以真正阻塞點應該是ThreadedRenderer.nFence這個位置的執行的方法;ANR問題涵蓋的內容非常多,需要多積累經驗,才能比較舒暢的分析這類問題;
"main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 obj=0x74637280 self=0xa9985400
| sysTid=9816 nice=0 cgrp=default sched=0/0 handle=0xac61b534
| state=S schedstat=( 0 0 0 ) utm=150 stm=135 core=2 HZ=100
| stack=0xbe7fd000-0xbe7ff000 stackSize=8MB
| held mutexes=
native: #00 pc 000173e4 /system/lib/libc.so (syscall+28)
native: #01 pc 000b6a3d /system/lib/libart.so (__6ThreadE+92)
native: #02 pc 003f101b /system/lib/libart.so (_ZN3artL12GoToRunnableEPNS_6ThreadE+230)
native: #03 pc 003f0f0b /system/lib/libart.so (_ZN3art12JniMethodEndEjPNS_6ThreadE+8)
native: #04 pc 00e7a58f /data/dalvik-cache/arm/system@[email protected] (Java_android_view_ThreadedRenderer_nFence__J+90)
at android.view.ThreadedRenderer.nFence(Native method)
at android.view.ThreadedRenderer.fence(ThreadedRenderer.java:859)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2651)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2228)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1248)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6330)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
㈣ 如何分析解決androidanr
2:耗時的工作(比如資料庫操作,I/O,連接網路或者別的有可能阻礙UI線程的操作)把它放入單獨的線程處理
3:盡量用Handler來處理UIthread和別的thread之間的交互
如何調查並解決ANR
1:首先分析log
2: 從trace.txt文件查看調用stack.
3: 看代碼
4:仔細查看ANR的成因(iowait?block?memoryleak?)
分析ANR
先看個LOG:
04-01 13:12:11.572 I/InputDispatcher( 220): Application is not responding:Window{2b263310com.android.email/com.android.email.activity.SplitScreenActivitypaused=false}. 5009.8ms since event, 5009.5ms since waitstarted
04-0113:12:11.572 I/WindowManager( 220): Input event dispatching timedout sending tocom.android.email/com.android.email.activity.SplitScreenActivity
04-01 13:12:14.123 I/Process( 220): Sending signal. PID: 21404 SIG: 3---發生ANR的時間和生成trace.txt的時間
04-01 13:12:14.123 I/dalvikvm(21404):threadid=4: reacting to signal 3
……
04-0113:12:15.872 E/ActivityManager( 220): ANR in com.android.email(com.android.email/.activity.SplitScreenActivity)
04-0113:12:15.872 E/ActivityManager( 220): Reason:keyDispatchingTimedOut
04-0113:12:15.872 E/ActivityManager( 220): Load: 8.68 / 8.37 / 8.53
04-0113:12:15.872 E/ActivityManager( 220): CPUusage from 4361ms to 699ms ago ----CPU在ANR發生前的使用情況
04-0113:12:15.872 E/ActivityManager( 220): 5.5%21404/com.android.email: 1.3% user + 4.1% kernel / faults: 10 minor
04-0113:12:15.872 E/ActivityManager( 220): 4.3%220/system_server: 2.7% user + 1.5% kernel / faults: 11 minor 2 major
04-0113:12:15.872 E/ActivityManager( 220): 0.9%52/spi_qsd.0: 0% user + 0.9% kernel
04-0113:12:15.872 E/ActivityManager( 220): 0.5%65/irq/170-cyttsp-: 0% user + 0.5% kernel
04-0113:12:15.872 E/ActivityManager( 220): 0.5%296/com.android.systemui: 0.5% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 100%TOTAL: 4.8% user + 7.6% kernel + 87% iowait
04-0113:12:15.872 E/ActivityManager( 220): CPUusage from 3697ms to 4223ms later:-- ANR後CPU的使用量
04-0113:12:15.872 E/ActivityManager( 220): 25%21404/com.android.email: 25% user + 0% kernel / faults: 191 minor
04-0113:12:15.872 E/ActivityManager( 220): 16% 21603/__eas(par.hakan: 16% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 7.2% 21406/GC: 7.2% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 1.8% 21409/Compiler: 1.8% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 5.5%220/system_server: 0% user + 5.5% kernel / faults: 1 minor
04-0113:12:15.872 E/ActivityManager( 220): 5.5% 263/InputDispatcher: 0% user + 5.5% kernel
04-0113:12:15.872 E/ActivityManager( 220): 32%TOTAL: 28% user + 3.7% kernel
從LOG可以看出ANR的類型,CPU的使用情況,如果CPU使用量接近100%,說明當前設備很忙,有可能是CPU飢餓導致了ANR
如果CPU使用量很少,說明主線程被BLOCK了
如果IOwait很高,說明ANR有可能是主線程在進行I/O操作造成的
除了看LOG,解決ANR還得需要trace.txt文件,
如何獲取呢?可以用如下命令獲取
$chmod 777 /data/anr
$rm /data/anr/traces.txt
$ps
$kill -3 PID
adbpull data/anr/traces.txt ./mytraces.txt
從trace.txt文件,看到最多的是如下的信息:
-----pid 21404 at 2011-04-01 13:12:14 -----
Cmdline: com.android.email
DALVIK THREADS:
(mutexes: tll=0tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1NATIVE
| group="main" sCount=1 dsCount=0obj=0x2aad2248 self=0xcf70
| sysTid=21404 nice=0 sched=0/0cgrp=[fopen-error:2] handle=1876218976
atandroid.os.MessageQueue.nativePollOnce(Native Method)
atandroid.os.MessageQueue.next(MessageQueue.java:119)
atandroid.os.Looper.loop(Looper.java:110)
at android.app.ActivityThread.main(ActivityThread.java:3688)
at java.lang.reflect.Method.invokeNative(Native Method)
atjava.lang.reflect.Method.invoke(Method.java:507)
atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
at dalvik.system.NativeStart.main(Native Method)
說明主線程在等待下條消息進入消息隊列
㈤ android traceview在哪
1.假定採用Debug.startMethodTracing和Debug.stopMethodTracing方式錄制了trace文件。如本經驗中的abc.trace文件
2.啟動cmd。進入到trace文件所在的目錄。
執行traceview trace文件。如圖,traceview E:\\abc.trace
3.在traceviwe工具中,上面的Panel是timeline Panel,如圖的例子:
4.在traceviwe工具中,下面的panel是性能分析的panel,如圖的例子:
5.還可以使用dmtracemp工具生成性能圖
㈥ 求教,如何抓取Android trace log
Android開發中,所的有輸出都在logcat中 包含System.out輸出和printStackTrace()輸出都在Logcat中,Android開發,建議使用android提供的Log工具類來列印信息。
找到Logcat視圖的方式:
Eclipse 點擊 Window
Show View會出來一個對話框
點擊Ok按鈕時,會在控制台窗口出現LogCat視圖
android.util.Log常用的方法有以下5個:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。根據首字母對應VERBOSE,DEBUG,INFO, WARN,ERROR。
1、Log.v 的調試顏色為黑色的,任何消息都會輸出,這里的v代表verbose啰嗦的意思,平時使用就是Log.v("","");
2、Log.d的輸出顏色是藍色的,僅輸出debug調試的意思,但他會輸出上層的信息,過濾起來可以通過DDMS的Logcat標簽來選擇.
3、Log.i的輸出為綠色,一般提示性的消息information,它不會輸出Log.v和Log.d的信息,但會顯示i、w和e的信息
4、Log.w的意思為橙色,可以看作為warning警告,一般需要我們注意優化Android代碼,同時選擇它後還會輸出Log.e的信息。
5、Log.e為紅色,可以想到error錯誤,這里僅顯示紅色的錯誤信息,這些錯誤就需要認真的分析,查看棧的信息了。
㈦ android trace文件怎麼看
後綴名是什麼 是.txt嗎?
Log分析 你還可以去data/anr的目錄下把trace.txt這個文件拷貝出來,在該文件中會寫了產生anr的函數堆棧可以幫助分析
㈧ Android開發中,有哪些好方法可以檢測內存泄露和性能
下面是回答的內容
內存泄露,是Android開發者最頭疼的事。可能一處小小的內存泄露,都可能是毀於千里之堤的蟻穴。怎麼才能檢測內存泄露呢?網上教程非常多,不過很多都是使用Eclipse檢測的, 其實1.3版本以後的Android Studio 檢測內存非常方便, 如果結合上MAT工具,LeakCanary插件,一切就變得so easy了。
熟悉Android Studio界面工欲善其事,必先利其器。
我們接下來先來熟悉下Android Studio的界面
結果
非獨占時間:某函數佔用的CPU時間,包含內部調用其它函數的CPU時間。
獨占時間:某函數佔用CPU時間,但不含內部調用其它函數所佔用的CPU時間。
我們如何判斷可能有問題的方法?
通過方法的調用次數和獨占時間來查看,通常判斷方法是:
如果方法調用次數不多,但每次調用卻需要花費很長的時間的函數,可能會有問題。
如果自身佔用時間不長,但調用卻非常頻繁的函數也可能會有問題。
綜述
上面給大家介紹了若干使用Android Studio檢查程序性能的工具,工具永遠是輔助,不要因為工具耽誤太長時間。如果有問題,歡迎大家糾正。
㈨ android 怎麼解析tra文件
對於從事Android開發的人來說,遇到ANR(Application Not Responding)是比較常見的問題。一般情況下,如果有ANR發生,系統都會在/data/anr/目錄下生成trace文件,通過分析trace文件,可以定位產生ANR的原因。產生ANR的原因有很多,比如CPU使用過高、事件沒有得到及時的響應、死鎖等,下面將通過一次因為死鎖導致的ANR問題,來說明如何通過trace文件分析ANR問題。
對應的部分trace文件內容如下:
"PowerManagerService" prio=5 tid=24 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x41dd0eb0 self=0x5241b218
| sysTid=567 nice=0 sched=0/0 cgrp=apps handle=1380038664
| state=S schedstat=( 6682116007 11324451214 33313 ) utm=450 stm=219 core=1
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:~13045)
- waiting to lock <0x41a874a0> (a com.android.server.am.ActivityManagerService) held by tid=12 (android.server.ServerThread)
at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1144)
at com.android.server.power.PowerManagerService$DisplayBlankerImpl.unblankAllDisplays(PowerManagerService.java:3442)
at com.android.server.power.DisplayPowerState$PhotonicMolator$1.run(DisplayPowerState.java:456)
at android.os.Handler.handleCallback(Handler.java:800)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:194)
at android.os.HandlerThread.run(HandlerThread.java:60)
"Binder_B" prio=5 tid=85 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x42744770 self=0x58329e88
| sysTid=3700 nice=-20 sched=0/0 cgrp=apps handle=1471424616
| state=S schedstat=( 1663727513 2044643318 6806 ) utm=132 stm=34 core=1
at com.android.server.power.PowerManagerService$DisplayBlankerImpl.toString(PowerManagerService.java:~3449)
- waiting to lock <0x41a7e420> (a com.android.server.power.PowerManagerService$DisplayBlankerImpl) held by tid=24 (PowerManagerService)
at java.lang.StringBuilder.append(StringBuilder.java:202)
at com.android.server.power.PowerManagerService.mp(PowerManagerService.java:3052)
at android.os.Binder.mp(Binder.java:264)
at android.os.Binder.onTransact(Binder.java:236)
at android.os.IPowerManager$Stub.onTransact(IPowerManager.java:373)
at android.os.Binder.execTransact(Binder.java:351)
at dalvik.system.NativeStart.run(Native Method)
"android.server.ServerThread" prio=5 tid=12 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x41a76178 self=0x507837a8
| sysTid=545 nice=-2 sched=0/0 cgrp=apps handle=1349936616
| state=S schedstat=( 15368096286 21707846934 69485 ) utm=1226 stm=310 core=0
at com.android.server.power.PowerManagerService.isScreenOnInternal(PowerManagerService.java:~2529)
- waiting to lock <0x41a7e2e8> (a java.lang.Object) held by tid=85 (Binder_B)
at com.android.server.power.PowerManagerService.isScreenOn(PowerManagerService.java:2522)
at com.android.server.wm.WindowManagerService.(WindowManagerService.java:7749)
at com.android.server.wm.WindowManagerService.setEventDispatching(WindowManagerService.java:7628)
at com.android.server.am.ActivityManagerService.updateEventDispatchingLocked(ActivityManagerService.java:8083)
at com.android.server.am.ActivityManagerService.wakingUp(ActivityManagerService.java:8077)
at com.android.server.power.Notifier.sendWakeUpBroadcast(Notifier.java:474)
at com.android.server.power.Notifier.sendNextBroadcast(Notifier.java:455)
at com.android.server.power.Notifier.access$700(Notifier.java:62)
at com.android.server.power.Notifier$NotifierHandler.handleMessage(Notifier.java:600)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at com.android.server.ServerThread.run(SystemServer.java:1328)
從trace文件看,是因為TID為24的線程等待一個TID為12的線程持有的鎖,TID為12的線程等待一個TID為85的線程持有的鎖,而TID為85的線程確等待一個TID為24的線程持有的鎖,導致了循環等待的現象,對應的trace文件的語句如下:
TID 24:- waiting to lock <0x41a874a0> (a com.android.server.am.ActivityManagerService) held by tid=12 (android.server.ServerThread)
TID 12: - waiting to lock <0x41a7e2e8> (a java.lang.Object) held by tid=85 (Binder_B)
TID 85:- waiting to lock <0x41a7e420> (a com.android.server.power.PowerManagerService$DisplayBlankerImpl) held by tid=24 (PowerManagerService)
既然是死鎖,那麼先看各線程都有那些鎖。
先看TID=24的線程的棧頂,ActivityManagerService的broadcastIntent函數代碼如下:
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo,
resultCode, resultData, map, requiredPermission, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
可以看到TID=24需要ActivityManagerService這個鎖。再看TID=12線程的棧頂,PowerManagerService的isScreenOnInternal函數代碼如下:
private boolean isScreenOnInternal() {
synchronized (mLock) {
return !mSystemReady
|| mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF;
}
}
可以看到需要PowerManagerService的mlock這個鎖。最後看TID=85線程的棧頂,同樣在PowerManagerService裡面,內部類DisplayBlankerImpl的toString函數:
public String toString() {
synchronized (this) {
return "blanked=" + mBlanked;
}
}
這是在內部類DisplayBlankerImpl裡面實現的,所以需要DisplayBlankerImpl這個鎖。
對應的表格如下:
表一 各線程等待的鎖情況
從表一來看,沒有出現死鎖現象,似乎並不是我們所想的那樣。難道不是死鎖?開始有點小懷疑自己了,難道別的原因導致的。也許只看調用堆棧的頂端可能不行,棧頂只能看出各線程需要的鎖,不能僅看自己要什麼吧!一味索取可不好!人不是這樣做的!看一下整個的堆棧調用流程,看看自己擁有了那些鎖。
跟蹤TID=24線程的堆棧,在PowerManagerService內部類DisplayBlankerImpl的unblankAllDisplays函數中持有鎖:
public void unblankAllDisplays() {
synchronized (this) {
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
mDisplayManagerService.();
mBlanked = false;
///M: add for tvout and hdmi
mTvOut.tvoutPowerEnable(true);
mHDMI.hdmiPowerEnable(true);
///@}
if (DEBUG) {
Slog.d(TAG_P, "unblankAllDisplays out ...");
}
if (mBootCompleted) {
Intent intent = new Intent(ACTION_LOCK_SCREEN_SHOW);
mContext.sendBroadcast(intent);
}
}
}
最後發送廣播的代碼,是我們自己添加的。根據unblankAllDisplays函數和broadcastIntent函數,可以看到TID=24的線程此時持有了DisplayBlankerImpl鎖(unblankAllDisplays),等待ActivityManagerService鎖(broadcastIntent)釋放。
同樣,跟蹤TID=12線程的堆棧,在ActivityManagerService的wake_up函數中持有鎖:
public void wakingUp() {
if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.DEVICE_POWER);
}
synchronized(this) {
Slog.i(TAG, "wakingUp");
mWentToSleep = false;
updateEventDispatchingLocked();
comeOutOfSleepIfNeededLocked();
}
}
根據wakingUp函數和isScreenOnInternal函數,可以看到TID=12的線程持有ActivityManagerService鎖(wakingUp),等待PowerManagerService.mLock鎖(isScreenOnInternal)。到這,似乎看到了希望,迷霧要撥開了,有點小自信是死鎖導致的,但還不能最終下結論。
一鼓作氣,跟蹤TID=85線程的堆棧,在PowerManagerService的mp有持有鎖的操作:
protected void mp(FileDescriptor fd, PrintWriter pw, String[] args) {
....
synchronized (mLock) {
...
}
根據toString函數和mp函數,可以看到TID=85線程此時持有PowerManagerService.mLock鎖(mp),需要DisplayBlankerImpl(toString)。
㈩ android怎麼使用rpmbuild
對於從事Android開發的人來說,遇到ANR(Application Not Responding)是比較常見的問題。一般情況下,如果有ANR發生,系統都會在/data/anr/目錄下生成trace文件,通過分析trace文件,可以定位產生ANR的原因。產生ANR的原因有很多,比如CPU使用過高、事件沒有得到及時的響應、死鎖等,下面將通過一次因為死鎖導致的ANR問題,來說明如何通過trace文件分析ANR問題。
對應的部分trace文件內容如下:
"PowerManagerService" prio=5 tid=24 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x41dd0eb0 self=0x5241b218
| sysTid=567 nice=0 sched=0/0 cgrp=apps handle=1380038664
| state=S schedstat=( 6682116007 11324451214 33313 ) utm=450 stm=219 core=1
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:~13045)
- waiting to lock <0x41a874a0> (a com.android.server.am.ActivityManagerService) held by tid=12 (android.server.ServerThread)