- select 是操作系统提供的系统调用函数,通过它,我们可以把一个文件描述符的数组发给操作系统,让操作系统去遍历,确定哪个文件描述符可以读写,然后告诉我们去处理 。
- poll:它和 select 的主要区别就是,去掉了 select 只能监听 1024 个文件描述符的限制
- epoll:epoll 主要就是针对select的这三个可优化点进行了改进
1、内核中保存一份文件描述符集合,无需用户每次都重新传入,只需告诉内核修改的部分即可 。2、内核不再通过轮询的方式找到就绪的文件描述符,而是通过异步 IO 事件唤醒 。3、内核仅会将有 IO 事件的文件描述符返回给用户,用户也无需遍历整个文件描述符集合 。关于epoll机制就总结这么多啦 。
回到 MessageQueue的next 方法,看看哪里可能阻塞
同步屏障消息没移除导致next一直阻塞有一种情况,在存在同步屏障消息的情况下,当异步消息被处理完之后,如果没有及时把同步屏障消息移除,会导致同步消息一直没有机会处理,一直阻塞在nativePollOnce 。
同步屏障消息Android 是禁止App往MessageQueue插入同步屏障消息的,代码会报错
文章插图
系统一些高优先级的操作会使用到同步屏障消息,例如View在绘制的时候,最终都要调用ViewRootImpl的scheduleTraversals方法,会往MessageQueue插入同步屏障消息,绘制完成后会移除同步屏障消息 。
->ViewRootImpl@UnsupportedAppUsagevoid scheduleTraversals() {if (!mTraversalScheduled) {mTraversalScheduled = true;//插入同步屏障消息mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);if (!mUnbufferedInputDispatch) {scheduleConsumeBatchedInput();}notifyRendererOfFramePending();pokeDrawLockIfNeeded();}}void unscheduleTraversals() {if (mTraversalScheduled) {mTraversalScheduled = false;//移除同步屏障消息mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);mChoreographer.removeCallbacks(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);}}复制代码
为了保证View的绘制过程不被主线程其它任务影响,View在绘制之前会先往MessageQueue插入同步屏障消息,然后再注册Vsync信号监听,Choreographer$FrameDisplayEventReceiver就是用来接收vsync信号回调的Choreographer$FrameDisplayEventReceiver
private final class FrameDisplayEventReceiver extends DisplayEventReceiverimplements Runnable {...@Overridepublic void onVsync(long timestampNanos, long physicalDisplayId, int frame) {...//mTimestampNanos = timestampNanos;mFrame = frame;Message msg = Message.obtain(mHandler, this);//1、发送异步消息msg.setAsynchronous(true);mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);}@Overridepublic void run() {// 2、doFrame优先执行doFrame(mTimestampNanos, mFrame);}}复制代码
收到Vsync信号回调,注释1会往主线程MessageQueue post一个异步消息,保证注释2的doFrame优先执行 。doFrame才是View真正开始绘制的地方,会调用ViewRootImpl的doTraversal、performTraversals,
而performTraversals里面会调用我们熟悉的View的onMeasure、onLayout、onDraw 。
推荐阅读
- 6款提高win10性能的软件,让你的电脑越用越好用
- Clarinet性能和维护方法
- 性能测试之HTTP讲解+抓包工具
- SQL优化最干货总结 - MySQL
- 最值得推荐的5款5000元轻薄本,性能强颜值高,续航高达19.1小时
- 安全研究人员开发出可在检测到破解时自毁数据的Android应用
- 被忽视的显卡性能:视频硬件解码
- 无线网络优化——通信老姜的解读
- 吊打tomcat的高性能web服务器undertow
- 不加硬件如何提高电脑性能?不花一分钱8个技巧快速提高电脑性能