我知道线程有一个消息队列,处理程序能够向它们推送可运行程序或消息,但当我使用android Studio工具分析我的Android应用程序时,有一个奇怪的过程:
android.os.MessageQueue.nativePollOnce
它比所有其他进程更多地使用CPU。它是什么?我如何减少CPU在它上面花费的时间?你可以在下面找到分析器的结果。
发布于 2016-08-09 06:50:16
简短回答:
nativePollOnce
方法用于“等待”,直到下一个Message
可用。如果在此调用过程中花费的时间很长,则您的主(UI)线程没有实际的工作要做,而是等待下一个事件处理。没有必要担心这个问题。
说明:
因为“主线程”负责绘制UI和处理各种事件,所以它的Runnable
有一个处理所有这些事件的循环。该循环由Looper
管理,其工作非常简单:它处理MessageQueue
中的所有消息。
Message
被添加到队列中,例如作为对输入事件的响应,作为帧呈现回调,甚至是您自己的Handler.post
调用。有时主线程没有工作要做(即队列中没有消息),这可能发生在刚刚完成渲染单个帧之后(线程刚刚绘制了一个帧,并准备好下一个帧,只是等待适当的时间)。我们对MessageQueue
类中的两个方法很感兴趣:Message next()
和boolean enqueueMessage(Message, long)
。顾名思义,Message next()
从队列中获取并返回下一条消息。如果队列为空(并且没有返回任何内容),则该方法调用native void nativePollOnce(long, int)
,该方法将一直阻塞,直到添加新消息为止。此时,您可能会问nativePollOnce
是如何知道何时唤醒的。这是一个非常好的问题。当Message
被添加到队列时,框架会调用enqueueMessage
方法,该方法不仅会将消息插入到队列中,而且还会在需要唤醒队列时调用native static void nativeWake(long)
。nativePollOnce
和nativeWake
的核心魔力发生在native (actually, C++) code中。原生MessageQueue利用了一个名为epoll
的系统调用,它允许监视IO事件的文件描述符。nativePollOnce
对某个文件描述符调用epoll_wait
,而nativeWake
写入描述符,这是epoll_wait
等待的IO操作之一。然后,内核将epoll等待线程从等待状态中取出,该线程继续处理新消息。如果您熟悉Java语言的Object.wait()
和Object.notify()
方法,就可以想象nativePollOnce
大致等同于Object.wait()
和Object.notify()
的nativeWake
,只是它们的实现完全不同:nativePollOnce
使用epoll
,而Object.wait()
使用<代码>C37 Linux调用。值得注意的是,nativePollOnce
和Object.wait()
都不会浪费CPU周期,因为当线程进入这两种方法时,出于线程调度的目的而禁用了它(引用Object
类的javadoc )。但是,一些分析器可能会错误地将epoll等待(甚至对象等待)线程识别为正在运行并消耗CPU时间,这是不正确的。如果这些方法实际上浪费了CPU周期,所有空闲的应用程序都将使用100%的CPU,从而加热和减慢设备。
结论:
你不应该担心nativePollOnce
。它只是指示所有消息的处理已经完成,线程等待下一条消息。嗯,这仅仅意味着你不会给你的主线程太多的工作;)
https://stackoverflow.com/questions/38818642
复制相似问题