trace文件android
1. 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)。
2. 跟蹤的trace文件,需要用什麼工具回放
Traceview的使用步驟
分為以下三步:
1. 選擇追蹤范圍加入記錄代碼
2.利用tools下的工具trace view打開.trace文件
3.分析trace文件
1. 選擇追蹤范圍加入記錄代碼
首先,必須在程序當中加入代碼,以便生成trace文件,有了這個trace文件才可以將其轉化為圖形。
要添加的代碼如下:
1 Debug.startMethodTracing(「wirelessqa」); //開始
2 Debug.stopMethodTracing(); //結束
其中參數wirelessqa是要創建的trace文件的名稱,wirelessqa.trace。默認路徑是/sdcard/wirelessqa.trace,也可以自己制定/data/log/wirelessqa,表示文件在/data/log/wirelessqa.trace。
實例代碼參考:
01 publicclass MainActivity extends Activity {
02
03 @Override
04 protectedvoid onCreate(Bundle savedInstanceState) {
05 super.onCreate(savedInstanceState);
06 setContentView(R.layout.activity_main);
07 setTitle(this.getClass().getName());
08 View toLoginView = findViewById(R.id.to_login);
09 // 開始記錄 sdcard/wirelessqa.trace文件
10 Debug.startMethodTracing("wirelessqa");
11 toLoginView.setOnClickListener(new View.OnClickListener() {
12
13 publicvoid onClick(View view) {
14 Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
15 startActivity(intent);
16 }
17 });
18 }
19
20 @Override
21 protectedvoid onStop() {
22 super.onStop();
23 Debug.stopMethodTracing();// 結束記錄wirelessqa.trace
24 }
25 }
說明:
開發文檔中說可以在activity的onCreate()中添加Debug.startMethodTracing(), 而在onDestroy()中添加Debug.stopMethodTracing(),但是在實際的測試時發現這種方式其實並不好用,因為通常情況下我們的activity的onDestroy()是由系統決定何時調用的,因此可能等了很長時間都不會得到這個trace文件。
因此決定在onStop()中來調用Debug.stopMethodTracing()。這樣當我們切換到其它activity或者點擊home鍵的時候onStop()就會被調用,我們也就可以得到完整的trace file。
別忘了加入訪問SD卡的許可權
1 <uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
2 <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2.利用tools下的工具trace view打開.trace文件
3. 分析trace文件
3. 如何分析trace文件
Oracle-trace文件分析
如果一個系統的執行效率比較低,一個比較好的方法是通過跟蹤用戶的會話並且使用tkprof工具使用排序功能格式化輸出,從而找出有問題的sql語句。
例如首先從os上利用top命令找到當前佔用cpu資源最高的一個進程的PID號9999;
然後在資料庫中根據PID號找到相應的sid和serial#
select s.sid,s.serial# from v$session s,v$process p where s.paddr=p.addr and p.spid='9999';
然後通過exec dbms_monitor.session_trace_enable(sid,serial#)開啟trace;
最後利用tkprof察看trace輸出。
開啟Trace文件輸出
可以通過以下方法開啟Trace文件輸出(需要ALTER SESSION系統許可權):
1) alter session/system set sql_trace=true
2) exec dbms_monitor.session_trace_enable/dbms_monitor.database_trace_enable
3) alter session set events '10046 trace name context forever, level 12'
Trace文件的位置
4. 求教,如何抓取Android trace log
您好,很高興為您解答。1,安裝SDK(參考androidsdk環境安裝)2,使用數據線鏈接手機,在手機助手的sdcard中建立一個1.log的文件3,程序運行cmd4,輸入抓取命令:logcat-s'*:E'>/mmt/sdcard/1.log5,使用手機崩潰一次6,查看日誌抓取文件,分不清楚是那個時間段所造成的後果7,加入命令:-vtime就會顯示出時間8,輸入命令logcat-vtime-s'*:E'>/mmt/sdcard/1.log9,查看結果如若滿意,請點擊右側【採納答案】,如若還有問題,請點擊【追問】希望我的回答對您有所幫助,望採納!~O(∩_∩)O~
5. Android ANR trace 報告怎麼看
後綴名是什麼是.txt嗎?Log分析你還可以去data/anr的目錄下把trace.txt這個文件拷貝出來,在該文件中會寫了產生anr的函數堆棧可以幫助分析
6. android trace 文件怎麼分析
對於從事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)
7. 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)
8. 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工具生成性能圖
9. android trace文件怎麼看
後綴名是什麼 是.txt嗎?
Log分析 你還可以去data/anr的目錄下把trace.txt這個文件拷貝出來,在該文件中會寫了產生anr的函數堆棧可以幫助分析
10. 如何對Android的本地代碼進行profiling
現在用Android native code寫程序庫的人越來越多。對於那些需要寫的庫實時性要求特別強的應用,通過profiling來進行優化是一個非常有用的特性,因為它能幫你理解程序編譯後的本質,比如多少instruction,哪些method調用多少次,多長時間,等等。
Android開發環境提供了Traceview這樣一個工具,可以點到這個鏈接裡面去看官方對他的介紹。總的來說,就是它提供給程序開發者目標程序的執行日誌,以此幫助你調試程序和優化性能。有兩種方法能夠聲稱traceview所需的log,一種是利用DDMS的profiling特性,通過控制什麼時候開始和結束logging來獲得log。這個方法在你沒有程序源代碼的時候有用,因為只需要Run程序就能獲得log信息,但是沒有精準的起始中止控制。另一種是通過將Android自帶的Debug類加到code中,然後調用裡面的method來開始和中止trace信息的紀錄。這個方法能讓開發者非常精準地控制什麼時候開始紀錄,什麼時候結束紀錄,因為開始和技術都是在code中執行的。
對於Java程序來說,官方網頁介紹了一個標准流程,就是在程序中引入Debug類,然後在你想要開始紀錄profiling信息的時候調用startMethodTracing(),然後在准備結束的時候調用stopMethodTracing()方法。紀錄的log文件默認放在sdcard中。
然而對於本地native代碼,該方法就無效了。原因是這個方式只能trace你的java層的方法和其對Android API的調用,卻無法trace Android API背後的那些方法,也無法trace你自己寫的native code。如果你希望trace這些更底層的代碼,就需要用Debug類提供的Debug.startNativeTracing()和 Debug.stopNativeTracing()。而且,這個配對只能工作的虛擬機emulator中,因為只有trace qemu emulator,才能去trace每一個進程的每一條cpu指令,甚至包括內核的代碼,我們也才能獲得更多的信息比如context switch,cache misses。
下面就來看看,利用該方法對來profile native code是怎樣一個流程:
1. 新建一個Android Virtual Device,給一個名字,比如Profile。可以在AVD manager中創建。
2. 在命令行中通過命令」emulator -avd -trace
」 來運行該AVD。比如emulator -avd Profile -trace myTrace。
3. 將startNativeTracing()和stopNativeTracing()添加到你想profile的代碼中。
4. 在Eclipse中build代碼,確保沒有錯誤。安裝到正在運行的AVD中。
5. 去AVD中運行代碼,確保你希望trace的代碼段正常運行了。如果你觀察運行AVD的那個terminal的窗口,應該會有比如「–start tracing–」 和 「–stop tracing–」這樣的消息出現,這就說明代碼正常運行了。
6. App運行完畢後,退出emulator。
7. 去你的用戶目錄找trace文件。這個目錄是存儲你AVD settings的目錄,默認一般都在/Home/User/.android/avd/下。這個User是你自己的用戶名,如果你是用的Mac或者Linux,這個路徑也就是~/.android/avd。
8. 找到和你AVD名字對應的文件夾,裡面有另一個子文件夾,命名就是你的trace名字,比如這里就是myTrace。裡面的文件包括:
qtrace.bb
qtrace.exc
qtrace.insn
qtrace.method
qtrace.pid
qtrace.static
9.你需要用tracedmmp這個工具來將這些文件轉化為符合Traceview格式的文件。問題在於,坑爹的Android SDK/NDK環境不原生提供這個工具。所以……..請看下一步
10. 好吧,這個工具來自於Android的源代碼環境。那我們需要做的,就是下載整個Android源代碼,編譯。這個過程通常會持續……一個小時以上。請參考官方手冊來進行編譯。如果你使用的是Linux,恭喜你,什麼別的資料都不用找,就一步一步按照手冊來就行了。如果你是Mac用戶……哥們,還是按照官方手冊來吧,但過程就聽天由命了。
11. Okay,假設到這里,你已經完成了整個Android源代碼的編譯。接下來,在源代碼的根目錄下運行「source build/envsetup.sh」,然後將根目錄下的/out/host/xxxx/bin加到PARH路徑中。xxx表示你的編譯平台。這下你就可以run tracedmmp了。開一個終端,執行「tracedmmp ~/.android/avd/Profile/myTrace/」,tracedmmp去分析剛才那些五花八門的二進制文件,挖掘裡面的symbolic信息,然後將其和trace數據對應。等一小會,就可以得到instruction的信息,並會生成一個更詳細的包括所有profiling信息的html文檔,這個文檔和Traceview兼容的,可以直接打開,也可以用Traceview工具分析。
這樣,整個profiling過程就結束了。
需要注意一點的是,這個方法和method tracing比有一個局限,就是因為工作在真實設備上,所以emulator不能模擬所有的真實設備效果,比如memory contention和bus contention,同時也無法模擬真實的cache效果,因為emulator中的cache設計是大大簡化了的。
