java nio空轮循_Java nio 空轮询bug到底是什么
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到底是什么相关推荐
- java nio 写事件_Java NIO
java Nio Selector 选择器 Buffer 缓冲器 Channel 通道 Selector是NIO的核心,是channel的管理者,通过执行select()阻塞方式,监听是否有chann ...
- java 接口文件夹_Java NIO.2 使用Path接口来监听文件、文件夹变化
Java7对NIO进行了大的改进,新增了许多功能: •对文件系统的访问提供了全面的支持 •提供了基于异步Channel的IO 这些新增的IO功能简称为 NIO.2,依然在java.nio包下. 早期的 ...
- java nio底层实现_Java NIO 底层原理
一.概念说明 1.内核态(内核空间)和用户态(用户空间)的区别和联系? 用户空间是用户进程所在的内存区域,系统空间是操作系统所在的内存区域.为了保证内核的安全,处于用户态的程序只能访问用户空间,而处于 ...
- java nio channel原理_Java NIO 选择器(Selector)与通道(Channel) 原理 | 学步园
NIO底层实现poll, epoll(jdk1.5update 9 和jdk1.6 仅限于 linux 2.6以上 ) Java NIO 选择器(Selector) 知识预备 (linux epo ...
- java nio.2群发_JAVA NIO TCP SOCKET 聊天群发
以前都是用一般的socket编程,用线程来控制.最近突然用nio来做些东西. nio的好处我来说一下:第一,读写都是基于块的,效率高.第二,通过引入selector,简化了网络编程模型,异步非阻塞. ...
- java selector 源码_Java NIO核心组件-Selector和Channel
昨天我们介绍了一下SelectorProvider和IO multiplexing.特别是IO multiplexing中的epoll系统调用,是Linux版本的Java的NIO的核心实现. 那今天我 ...
- java channel源码_java nio ServerSocketChannel源码分析
/** * 创建新实例 * * @param provider * The provider that created this channel */ protected ServerSocketCh ...
- java resourse 报错_java.nio.file.InvalidPathException: Illegal char :
一.报错: java.nio.file.InvalidPathException: Illegal char <:>at sun.nio.fs.WindowsPathParser.norm ...
- java nio 强制关闭_Java NIO服务器:远程主机强迫关闭了一个现有的连接
Java NIO聊天室 中,若客户端强制关闭,服务器会报"java.io.IOException: 远程主机强迫关闭了一个现有的连接.",并且服务器会在报错后停止运行,错误的意思就 ...
最新文章
- 产品经理经验谈50篇(三):在设定产品的功能优先级时,有哪些指导性原则与依据?
- linux 服务配置
- 2013\National _C_C++_A\1.填算式
- <scope>test</scope>的作用
- 计算机一级怎么描述,计算机一级「关于RGB正确的描述的是」相关单选题
- 微服务网关总结之 —— zuul
- Exchange Server 2016 独立部署/共存部署 (一)—— 前期准备
- 5G 兴起,物联网安全危机四伏
- ASP.NET中Form验证登录后反复跳转回登录页面的问题
- vscode extensions
- [ZZ]美图秀秀怎么加水印
- WPS批量根据标题设置目录编号问题与目录级别快速调整
- JavaScript 实现BASE58加密 中文英文数字都可以加密
- 关于买房提前还款问题
- psu 计算机 排名,PSU计算机工程专业研究生排名必然得当心去考察
- 如何登入MySQL数据库
- 多项式定理 matlab,泊松定理卡方分布及多项式拟合的MATLAB实现.pdf
- 令人感动的电影---虎兄虎弟
- rk3288之CPU定频实现(手动、内核)
- 酷狗服务器显示失败怎么回事,酷狗常见问题答疑
热门文章
- web.xml 详细介绍
- 微软张宏江出任金山CEO 求伯君正式退休
- sqlalchemy mysql教程_SQLAlchemy 教程 —— 基础入门篇
- linux关于管道通信,球热心人帮忙 关于linux环境下管道通信
- websocket html5 api,HTML5 新特性之 Websocket
- 用python写一个除法的函数_2、Python基础--除法、常用数学函数
- Selenium Grid- 让自动化分布式执行变得可能
- java21天打卡 day10-字符串2
- 2018北大计算机复试线,北京大学历年考研复试分数线_2018考研分数线
- 在职测试多年整理了自己常用的Linux命令...