最近公司的手機發現退出U盤模式後,在U盤存有圖片等內容比較多的情況下,滑動Launcher會有一段時間卡頓的現象。其實不是最近的項目纔有的問題,以前的項目就有,一直都沒有解決而已,頑疾。
當然,是在U盤不同模式直接切換的時候出現了問題,跟負責Vold的一起分析了一下,沒有發現什麼異常的地方。測試的時候發現,U盤存儲的內容越多,出現卡頓情況的時間越長,可能與media進程有關。不管怎麼樣,media是在後臺進行數據掃描,此時耗費CPU比較多,滑動桌面佔用的CPU資源也比較大,按這樣的思路,應該是在在CPU的使用上有衝突。top了一下,media在掃描的時候佔有的CPU確實比較高,在20%~40%之間。
1830 1 27% S 14 1230360K 53056K bg u0_a30 android.process.media
找負責media的同事一起看看吧!
media的同事說,所有的Android手機都一樣,在掃描的時候,CPU佔用都是這麼高,是沒法降低的,看來,media是無法解決了。但是我在對比其他廠家的機器時,卻沒有發現這個時候滑動Launcher卡頓的情況。我想,竟然覺得瓶頸在CPU上,把CPU全部設置成performance狀態,應該問題會有所改善吧?於是嘗試了一下,結果問題沒有任何的改善!
這是什麼情況?難道不是因爲競爭CPU而導致的卡頓。問題又毫無頭緒了,人生大起大落實在是太快了。明明可以看到Launcer和media佔用的CPU都很高,確不是因爲CPU的瓶頸導致的問題!!!雖然把CPU設置成performance後,CPU的使用率是降低了,但卡頓現象還是存在的。再用Systrace看了一下,沒有發現蛛絲馬跡。難道Launcher有問題?找Launcher同事一起分析!
跟Launcher同事一起看了一下Systrace文件,也沒有發現問題。當時討論的時候,我便瞎想起來,如果不是CPU引起的問題,那是不是因爲內存引起的呢?畢竟media跟Launcher競爭的資源並不多,除了CPU,也就只有內存影響比較大了。於是我們在剛開始滑動Launcher跟Launcher停止的時候都添加了log,過濾dalvikvm和添加的log後,發現,在卡頓的時候,都有GC的操作。在media掃描的時候,media不僅自己進行了大量的GC,還引起了system_server的GC:
02-11 10:35:30.008 D/dalvikvm(13845): GC_EXPLICIT freed 89K, 36% free 93009K/143540K, paused 2ms+6ms, total 50ms
02-11 10:35:30.058 D/dalvikvm(14440): GC_EXPLICIT freed 592K, 23% free 26298K/34112K, paused 2ms+5ms, total 30ms
02-11 10:35:30.388 D/dalvikvm(13845): GC_EXPLICIT freed 92K, 36% free 93009K/143540K, paused 4ms+10ms, total 91ms
02-11 10:35:30.728 D/dalvikvm(13845): GC_EXPLICIT freed 105K, 36% free 93011K/143540K, paused 3ms+8ms, total 65ms
02-11 10:35:30.768 D/dalvikvm(14440): GC_EXPLICIT freed 597K, 23% free 26298K/34112K, paused 1ms+4ms, total 19ms
02-11 10:35:30.968 D/dalvikvm(13845): GC_EXPLICIT freed 92K, 36% free 93009K/143540K, paused 2ms+9ms, total 70ms
02-11 10:35:31.238 D/dalvikvm(13845): GC_EXPLICIT freed 92K, 36% free 93009K/143540K, paused 3ms+7ms, total 70ms
02-11 10:35:31.288 D/dalvikvm(14440): GC_EXPLICIT freed 600K, 23% free 26299K/34112K, paused 1ms+4ms, total 28ms
02-11 10:35:31.568 D/dalvikvm(13845): GC_EXPLICIT freed 183K, 36% free 93025K/143540K, paused 3ms+6ms, total 77ms
02-11 10:35:31.828 D/dalvikvm(13845): GC_EXPLICIT freed 102K, 36% free 93014K/143540K, paused 5ms+6ms, total 65ms
02-11 10:35:31.868 D/dalvikvm(14440): GC_EXPLICIT freed 600K, 23% free 26299K/34112K, paused 1ms+3ms, total 25ms
02-11 10:35:32.128 D/dalvikvm(13845): GC_EXPLICIT freed 107K, 36% free 93015K/143540K, paused 5ms+8ms, total 83ms
02-11 10:35:32.418 D/dalvikvm(13845): GC_EXPLICIT freed 91K, 36% free 93013K/143540K, paused 4ms+10ms, total 89ms
02-11 10:35:32.458 D/dalvikvm(14440): GC_EXPLICIT freed 609K, 23% free 26299K/34112K, paused 1ms+3ms, total 21ms
02-11 10:35:32.658 D/dalvikvm(13845): GC_EXPLICIT freed 104K, 36% free 93015K/143540K, paused 2ms+7ms, total 56ms
02-11 10:35:32.878 D/dalvikvm(13845): GC_EXPLICIT freed 91K, 36% free 93014K/143540K, paused 3ms+8ms, total 66ms
13845和14440分別是system_server跟media進程:
system 13845 13799 1459616 224164 ffffffff 401034ac S system_server
u0_a30 14440 13799 1235768 53220 ffffffff 401045b0 S android.process.media
當然,media的GC我們可以不用關心,我們關心的是system_server進程的GC,因爲system_server的GC是引起Launcher卡頓的原因。這個時候,Launcher的同事說,看來我的猜想是對的,我可以當什麼家了!!!
02-11 10:52:43.951 D/dalvikvm( 1048): #01 pc 0002c874 /system/lib/libdvm.so (dvmCollectGarbageInternal(GcSpec const*)+2132)
02-11 10:52:43.951 D/dalvikvm( 1048): #02 pc 000586fe /system/lib/libdvm.so (dvmCollectGarbage()+29)
02-11 10:52:43.951 D/dalvikvm( 1048): #03 pc 00029860 /system/lib/libdvm.so
02-11 10:52:43.951 D/dalvikvm( 1048): #04 pc 0002e50c /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
02-11 10:52:43.951 D/dalvikvm( 1048): #05 pc 000630d8 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+291)
02-11 10:52:43.951 D/dalvikvm( 1048): #06 pc 0004cc62 /system/lib/libdvm.so
02-11 10:52:43.951 D/dalvikvm( 1048): #07 pc 0004f1d0 /system/lib/libandroid_runtime.so
02-11 10:52:43.951 D/dalvikvm( 1048): #08 pc 0007391e /system/lib/libandroid_runtime.so (android::javaObjectForIBinder(_JNIEnv*, android::sp<android::IBinder> const&)+273)
02-11 10:52:43.951 D/dalvikvm( 1048): #09 pc 0006c2ee /system/lib/libandroid_runtime.so
02-11 10:52:43.951 D/dalvikvm( 1048): #10 pc 000203cc /system/lib/libdvm.so (dvmPlatformInvoke+112)
02-11 10:52:43.951 D/dalvikvm( 1048): #11 pc 0005107e /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+397)
02-11 10:52:43.951 D/dalvikvm( 1048): #12 pc 00029860 /system/lib/libdvm.so
02-11 10:52:43.951 D/dalvikvm( 1048): #13 pc 0002e50c /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
02-11 10:52:43.951 D/dalvikvm( 1048): #14 pc 000630d8 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+291)
02-11 10:52:43.961 D/dalvikvm( 1048): #15 pc 0004fd2c /system/lib/libdvm.so
02-11 10:52:43.961 D/dalvikvm( 1048): #16 pc 0006df0c /system/lib/libandroid_runtime.so
02-11 10:52:43.961 D/dalvikvm( 1048): #17 pc 00072c56 /system/lib/libandroid_runtime.so
02-11 10:52:43.961 D/dalvikvm( 1048): #18 pc 00018182 /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+57)
02-11 10:52:43.961 D/dalvikvm( 1048): #19 pc 0001bdb2 /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+505)
02-11 10:52:43.961 D/dalvikvm( 1048): #20 pc 0001c1c2 /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+181)
02-11 10:52:43.961 D/dalvikvm( 1048): #21 pc 000200f4 /system/lib/libbinder.so
02-11 10:52:43.961 D/dalvikvm( 1048): #22 pc 00011a8a /system/lib/libutils.so (android::Thread::_threadLoop(void*)+213)
02-11 10:52:43.961 D/dalvikvm( 1048): #23 pc 0004f16a /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+65)
02-11 10:52:43.961 D/dalvikvm( 1048): #24 pc 0001157e /system/lib/libutils.so
02-11 10:52:43.961 D/dalvikvm( 1048): #25 pc 0000cb60 /system/lib/libc.so (__thread_entry+72)
02-11 10:52:43.961 D/dalvikvm( 1048): #26 pc 0000ccdc /system/lib/libc.so (pthread_create+208)