一、问题背景
在 NioEventLoop 事件循环中,Selector 一次次 select() 返回为 0,且没有事件被触发,形成空转,导致 CPU 占用 100%,系统资源白白浪费。这种情况尤其在 高并发、连接数多、IO事件少 的场景下更容易出现。
源码位置:NioEventLoop.java
Netty(基于 Java NIO)的底层用到了 Selector.select() 方法来阻塞等待事件。
private int select(long deadlineNanos) throws IOException {
if (deadlineNanos == NONE) {
return selector.select();
}
// Timeout will only be 0 if deadline is within 5 microsecs
long timeoutMillis = deadlineToDelayNanos(deadlineNanos + 995000L) / 1000000L;
return timeoutMillis <= 0 ? selector.selectNow() : selector.select(timeoutMillis);
}
二、可能出现的原因
- Linux内核(主要问题):在部分Linux的2.6的kernel中,poll和epoll对于突然中断的连接socket(如强制断网、防火墙中断连接)会对返回的eventSet事件集合置为POLLHUP,也可能是POLLERR,eventSet事件集合发生了变化,这就可能导致Selector会被唤醒(
select()/epoll_wait()立即返回0次事件); - JDKBug:尤其是 JDK 1.7~1.8 的 Selector 在 epoll 上的 bug:Selector.select() 会在 epoll 上不断空转;
- 其他线程调用
Se

最低0.47元/天 解锁文章
406

被折叠的 条评论
为什么被折叠?



