解释Logcat条目:threadid = 8:撤消后仍然挂起(sc = 1 dc = 1 s = Y)

Die*_*ner 6 android dalvik android-logcat

我的应用程序启动后,我正在运行十个AsyncTasks.有时,模拟器需要很长时间才能启动这些任务.发生这种情况时,我在log cat中看到以下消息:

D/dalvikvm(1983):threadid = 8:撤消后仍然暂停(sc = 1 dc = 1 s = Y)

当模拟器快速执行时,不会出现此消息.奇怪的是,这种行为今天没有任何修改就改变了.由于我已经向模拟器明确分配了512mb ram,它不再是非常慢~5min,现在~5s.在真实设备上,我从来没有执行过慢.

我想了解这个日志cat消息的含义.我知道具有指定id的线程在此状态下被挂起并且无法正常工作.但为什么?什么撤消?(sc = 1 dc = 1 s = Y)是什么意思?

fad*_*den 4

该消息来自dvmSuspendSelf(),当调试器(通过 JDWP 线程)要求线程挂起时调用该线程。

它应该工作的方式是(其中“我们”是一个线程):

  • JDWP 要求我们暂停
  • 我们告诉它我们已经暂停并去睡觉
  • 最终,调试器唤醒我们并继续

当虚拟机正在等待信号的条件变量时,会记录该消息,但由于某种原因,我们仍然被标记为挂起。代码注释:

/*
 * The condition was signaled but we're still suspended.  This
 * can happen if the debugger lets go while a SIGQUIT thread
 * dump event is pending (assuming SignalCatcher was resumed for
 * just long enough to try to grab the thread-suspend lock).
 */
Run Code Online (Sandbox Code Playgroud)

这种情况下的预期是,当信号到达时,我们会被意外唤醒(例如,system_server 认为存在 ANR,因为主线程没有响应,因为调试器已挂起它),如果我们再次循环,调试器将得到一个有机会清理我们并让我们上路。

日志消息打印以下值self->suspendCount(我们被告知要挂起自己多少次),self->dbgSuspendCount(有多少挂起请求来自调试器,因此如果调试器断开连接,我们可以“撤消”所有这些请求)以及值布尔值的self->isSuspended

注意“s=Y”标志在姜饼中消失了——线程悬挂的工作方式被改变了