epoll机制是Linux下一种高效的IO复用方式,相较于select和poll机制来说。其高效的原因是将基于事件的fd放到内核中来完成,在内核中基于红黑树+链表数据结构来实现,链表存放有事件发生的fd集合,然后在调用epoll_wait时返回给应用程序,由应用程序来处理这些fd事件。

使用IO复用,Linux下一般默认就是epoll,Java NIO在Linux下默认也是epoll机制,但是JDK中epoll的实现却是有漏洞的,其中最有名的java nio epoll bug就是即使是关注的select轮询事件返回数量为0,NIO照样不断的从select本应该阻塞的Selector.select()/Selector.select(timeout)中wake up出来,导致CPU 100%问题。如下图所示:

那么产生这个问题的原因是什么的?其实在 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6670302 上已经说明的很清楚了,比如下面是bug复现的一个场景:

OF THE PROBLEM :

in this situation..

0. server waits for connection

1. client connects and write message

2. server accepts and register OP_READ

3. server reads message and remove OP_READ from interest op set

4. client close the connection

5. server write message (without any reading.. surely OP_READ is not set)

6. server's select wakes up infinitely with return value 0

上面的场景描述的问题就是连接出现了RST,因为poll和epoll对于突然中断的连接socket会对返回的eventSet事件集合置为POLLHUP或者POLLERR,eventSet事件集合发生了变化,这就导致Selector会被唤醒,进而导致CPU 100%问题。根本原因就是JDK没有处理好这种情况,比如SelectionKey中就没定义有异常事件的类型。

class SelectionKey{

public static final int OP_READ = 1 <

public static final int OP_WRITE = 1 <

public static final int OP_CONNECT = 1 <

public static final int OP_ACCEPT = 1 <

既然nio epoll bug存在,那么能不能规避呢?答案是有的,比如netty就很巧妙的规避了这个问题,它的处理机制就是如果发生了这种情况,并且发生次数超过了SELECTOR_AUTO_REBUILD_THRESHOLD(默认512),则调用rebuildSelector()进行Selecttor重建,这样就不用管之前发生了异常情况的那个连接了。因为重建也是根据SelectionKey事件对应的连接来重新注册的。

该问题最早在 Java 6 发现,随后很多版本声称解决了该问题,但实际上只是降低了该 bug 的出现频率,目前从网上搜索到的资料显示,Java 8 还是存在该问题(当 Thrift 遇到 JDK Epoll Bug)。

最后一起来分析下,nio epoll bug不是linux epoll的问题,而是JDK自己实现epoll时没有考虑这种情况,或者说因为其他系统不存在这个问题,Java为了封装(比如SelectionKey 中的4个事件类型)的统一而没去处理?

这里思考下,如果想要从java nio层面上来解决这个问题,该如何做呢?

一种是nio事件类型SelectionKey新加一种"错误"类型,比如针对linux epoll中的epollhup和epollerr,如果出现这种事件,建议程序直接close socket,但这种方式相对来说对于目前的nio SelectionKey改动有点大,因为SelectionKey的定义目前是针对所有jdk平台的;还有一种是针对jdk nio 对epoll的封装中,对于epoll的epollhup和epollerr事件,epoll封装内部直接处理,比如close socket,但是这种方案也有一点尴尬的是,可能上层应用代码还保留有出现问题的socket引用,这时最好是应用程序能够感知这种情况来处理比较好。

Java nio空转问题由来已久,一般程序中是通过新建Selector的方式来屏蔽掉了JDK5/6的这个问题,因此,对于开发者来讲,还是尽量将JDK的版本更新到最新,或者使用NIO框架如Netty,Grizzly等进行研发,以免出更多的问题。

java nio空轮循_Java nio 空轮询bug到底是什么相关推荐

  1. java nio 写事件_Java NIO

    java Nio Selector 选择器 Buffer 缓冲器 Channel 通道 Selector是NIO的核心,是channel的管理者,通过执行select()阻塞方式,监听是否有chann ...

  2. java 接口文件夹_Java NIO.2 使用Path接口来监听文件、文件夹变化

    Java7对NIO进行了大的改进,新增了许多功能: •对文件系统的访问提供了全面的支持 •提供了基于异步Channel的IO 这些新增的IO功能简称为 NIO.2,依然在java.nio包下. 早期的 ...

  3. java nio底层实现_Java NIO 底层原理

    一.概念说明 1.内核态(内核空间)和用户态(用户空间)的区别和联系? 用户空间是用户进程所在的内存区域,系统空间是操作系统所在的内存区域.为了保证内核的安全,处于用户态的程序只能访问用户空间,而处于 ...

  4. java nio channel原理_Java NIO 选择器(Selector)与通道(Channel) 原理 | 学步园

    NIO底层实现poll, epoll(jdk1.5update 9  和jdk1.6  仅限于 linux 2.6以上 ) Java NIO 选择器(Selector) 知识预备 (linux epo ...

  5. java nio.2群发_JAVA NIO TCP SOCKET 聊天群发

    以前都是用一般的socket编程,用线程来控制.最近突然用nio来做些东西. nio的好处我来说一下:第一,读写都是基于块的,效率高.第二,通过引入selector,简化了网络编程模型,异步非阻塞. ...

  6. java selector 源码_Java NIO核心组件-Selector和Channel

    昨天我们介绍了一下SelectorProvider和IO multiplexing.特别是IO multiplexing中的epoll系统调用,是Linux版本的Java的NIO的核心实现. 那今天我 ...

  7. java channel源码_java nio ServerSocketChannel源码分析

    /** * 创建新实例 * * @param provider * The provider that created this channel */ protected ServerSocketCh ...

  8. java resourse 报错_java.nio.file.InvalidPathException: Illegal char :

    一.报错: java.nio.file.InvalidPathException: Illegal char <:>at sun.nio.fs.WindowsPathParser.norm ...

  9. java nio 强制关闭_Java NIO服务器:远程主机强迫关闭了一个现有的连接

    Java NIO聊天室 中,若客户端强制关闭,服务器会报"java.io.IOException: 远程主机强迫关闭了一个现有的连接.",并且服务器会在报错后停止运行,错误的意思就 ...

最新文章

  1. 产品经理经验谈50篇(三):在设定产品的功能优先级时,有哪些指导性原则与依据?
  2. linux 服务配置
  3. 2013\National _C_C++_A\1.填算式
  4. <scope>test</scope>的作用
  5. 计算机一级怎么描述,计算机一级「关于RGB正确的描述的是」相关单选题
  6. 微服务网关总结之 —— zuul
  7. Exchange Server 2016 独立部署/共存部署 (一)—— 前期准备
  8. 5G 兴起,物联网安全危机四伏
  9. ASP.NET中Form验证登录后反复跳转回登录页面的问题
  10. vscode extensions
  11. [ZZ]美图秀秀怎么加水印
  12. WPS批量根据标题设置目录编号问题与目录级别快速调整
  13. JavaScript 实现BASE58加密 中文英文数字都可以加密
  14. 关于买房提前还款问题
  15. psu 计算机 排名,PSU计算机工程专业研究生排名必然得当心去考察
  16. 如何登入MySQL数据库
  17. 多项式定理 matlab,泊松定理卡方分布及多项式拟合的MATLAB实现.pdf
  18. 令人感动的电影---虎兄虎弟
  19. rk3288之CPU定频实现(手动、内核)
  20. 酷狗服务器显示失败怎么回事,酷狗常见问题答疑

热门文章

  1. web.xml 详细介绍
  2. 微软张宏江出任金山CEO 求伯君正式退休
  3. sqlalchemy mysql教程_SQLAlchemy 教程 —— 基础入门篇
  4. linux关于管道通信,球热心人帮忙 关于linux环境下管道通信
  5. websocket html5 api,HTML5 新特性之 Websocket
  6. 用python写一个除法的函数_2、Python基础--除法、常用数学函数
  7. Selenium Grid- 让自动化分布式执行变得可能
  8. java21天打卡 day10-字符串2
  9. 2018北大计算机复试线,北京大学历年考研复试分数线_2018考研分数线
  10. 在职测试多年整理了自己常用的Linux命令...