Long monitor contention with owner
安卓Activity在finish后出现黑屏, 大概率是因为主线程卡死。 抓trace和logcat。
04-16 16:18:17.359 W/m.lianjia.beik(30714): Long monitor contention with owner Binder:30714_6 (32307) at void java.lang.Object.wait(long, int)(Object.java:-2) waiters=0 in android.content.ComponentName com.ke.ljplugin.component.service.server.PluginServiceServer$Stub.startService(android.content.Intent, android.os.Messenger) for 5.996s 04-16 16:18:17.360 W/m.lianjia.beik(30714): Current owner stack: 04-16 16:18:17.360 W/m.lianjia.beik(30714): (no managed stack frames) 04-16 16:18:17.360 W/m.lianjia.beik(30714): Contender stack: 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.ke.ljplugin.component.service.server.PluginServiceServer$Stub.startService(PluginServiceServer.java:554) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.ke.ljplugin.component.service.PluginServiceClient.startService(PluginServiceClient.java:106) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.ke.loader2.PluginContext.startService(PluginContext.java:516) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.lianjia.sdk.im.service.IMService.startIMService(link:100) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.lianjia.sdk.im.IMManager.initIMService(link:316) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.lianjia.sdk.im.IMManager.syncData(link:263) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.lianjia.sdk.im.IMManager.access$200(link:51) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.lianjia.sdk.im.IMManager$2.call(link:250) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.lianjia.sdk.im.IMManager$2.call(link:240) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at rx.internal.util.ActionSubscriber.onNext(ActionSubscriber.java:39) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:134) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:224) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at android.os.Handler.handleCallback(Handler.java:873) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at android.os.Handler.dispatchMessage(Handler.java:99) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at android.os.Looper.loop(Looper.java:201) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at android.app.ActivityThread.main(ActivityThread.java:6806) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at java.lang.reflect.Method.invoke(Native method) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 04-16 16:18:17.360 W/m.lianjia.beik(30714): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 04-16 16:18:17.360 W/m.lianjia.beik(30714): 04-16 16:18:17.388 I/Choreographer(30714): Skipped 361 frames! The application may be doing too much work on its main thread.
日志示例:“ 04-15 14:11:33.634 I/Choreographer(23776): Skipped 365 frames! The application may be doing too much work on its main thread. ” 触发条件: SKIPPED_FRAME_WARNING_LIMIT值为30, 即丢了30帧时打印这行日志, 对应0.5秒。
void doFrame(long frameTimeNanos, int frame) {
。。。
if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
Log.i(TAG, "Skipped " + skippedFrames + " frames! "
+ "The application may be doing too much work on its main thread.");
}
例如图片里startService的Cpu Time等于12.964ms, 但Real Time等于6013.609ms, 差距非常大。 原因在于startService使用了同步机制,即阻塞等待。 Logcat的第一句java.lang.Object.wait…, 当主线程卡死但没到ANR程度时, logcat里提示丢帧“too much work on its main thread"。
打印日志后可以搜索“too much”关键字。
