java nio的一个严重BUG
6u4才解决,sun的拖沓让人难以相信。这个BUG在server端容易出现,因为server端有频繁地接入断开连接。
使用jdk 6u4之前版本的nio框架都有这个隐患,除非你的框架很好地处理了这个可能的隐患。Grizzly的处理方式比较简单,也就是BUG报告里面提到的方式,在SelectionKey.cancel()之后马上进行了一次select调用将fd从poll(epoll)中移除:
try {
// cancel key,then select now to remove file descriptor
this.selector.selectNow();
} catch (IOException e) {
onException(e);
log.error("Selector selectNow fail", e);
}
实际上这样的解决方式还是留有隐患的,因为key的取消和这个selectNow操作很可能跟Selector.select操作并发地在进行,在两个操作之间仍然留有一个极小的时间窗口可能发生这个BUG。因此,你需要更安全地方式处理这个问题,jetty的处理方式是这样,连续的select(timeout)操作没有阻塞并返回0,并且次数超过了一个指定阀值,那么就遍历整个key set,将key仍然有效并且interestOps等于0的所有key主动取消掉;如果在这次修正后,仍然继续出现select(timeout)不阻塞并且返回0的情况,那么就重新创建一个新的Selector,并将Old
Selector的有效channel和对应的key转移到新的Selector上,
int selected=selector.select(wait);
now = System.currentTimeMillis();
_idleTimeout.setNow(now);
_timeout.setNow(now);
// Look for JVM bugs
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6403933
if (__JVMBUG_THRESHHOLD>0 && selected==0 && wait>__JVMBUG_THRESHHOLD && (now-before)<(wait/2) )
{
_jvmBug++;
if (_jvmBug>=(__JVMBUG_THRESHHOLD2))
{
synchronized (this)
{
_lastJVMBug=now;
// BLOODY SUN BUG !!! Try refreshing the entire selector.
final Selector new_selector = Selector.open();
for (SelectionKey k: selector.keys())
{
if (!k.isValid() || k.interestOps()==0)
continue;
final SelectableChannel channel = k.channel();
final Object attachment = k.attachment();
if (attachment==null)
addChange(channel);
else
addChange(channel,attachment);
}
_selector.close();
_selector=new_selector;
_jvmBug=0;
return;
}
}
else if (_jvmBug==__JVMBUG_THRESHHOLD || _jvmBug==__JVMBUG_THRESHHOLD1)
{
// Cancel keys with 0 interested ops
for (SelectionKey k: selector.keys())
{
if (k.isValid()&&k.interestOps()==0)
{
k.cancel();
}
}
return;
}
}
else
_jvmBug=0;
这个方案能比较好的在jdk 6u4之前的版本上解决这个BUG可能导致的问题。Mina和Netty没有看到有处理这个BUG的代码,如果我看错了,请留言告诉我。Yanf4j一直采用的是grizzly的方式,准备加上jetty的处理方案。当然,最简单的方案就是升级你的JDK :D
评论
https://jdk6.dev.java.net/6uNea.html
http://download.java.net/jdk6/6u18/promoted/b01/changes/JDK6u18.b01.list.html
例如:http://bugs.sun.com/view_bug.do?bug_id=6693490
看到了,6u3这个版本似乎问题多多。
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6670302 这个BUG跟我这里描述的相似,解决的方法也是一样。
100%,同样也是可以通过这里描述的方案解决的。
# re:
java nio的一个严重BUG 回复 更多评论
2012-05-09 16:54 by hengyunabc
以前也遇到过,在windows下测试了好久的程序,到linux下就出问题了,cpu跑满。
结果我是用每次select都用最新的SelectionKey来替换以前的SelectionKey,貌似没再出现cpu跑满的情况。
java nio的一个严重BUG的更多相关文章
- java nio的一个严重BUG(转)
这个BUG会在linux上导致cpu 100%,使得nio server/client不可用,具体的详情可以看这里http://bugs.sun.com/bugdatabase/view_bug.do ...
- java nio 写一个完整的http服务器 支持文件上传 chunk传输 gzip 压缩 使用过程 和servlet差不多
java nio 写一个完整的http服务器 支持文件上传 chunk传输 gzip 压缩 也仿照着 netty处理了NIO的空轮询BUG 本项目并不复杂 代码不多 ...
- Java多线程:Linux多路复用,Java NIO与Netty简述
JVM的多路复用器实现原理 Linux 2.5以前:select/poll Linux 2.6以后: epoll Windows: IOCP Free BSD, OS X: kqueue 下面仅讲解L ...
- Java - NIO
java.nio:NIO-2: NIO 面向流的IO体系一次只能处理一个或多个字节/字符,直至读取所有字节/符,且流中的数据不能前后移动.效率低,当数据源中没有数据时会阻塞线程.Java-4提供的新A ...
- java nio 与io区别
转自:http://blog.csdn.net/keda8997110/article/details/19549493 当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使 ...
- [翻译]java nio 概述
原文地址:http://tutorials.jenkov.com/java-nio/overview.html java NIO 包含一下核心内容: Channels Buffers Selector ...
- Java NIO之Selector
选择器是JavaNIO重磅推出的一个概念:在旧有的系统中为了跟踪多端口消息,需要为每一个端口配备一个线程做监听:但是有了selector就不需要了,一个Selector可以管理一众渠道(channel ...
- Java NIO中核心组成和IO区别
1.Java NIO核心组件 Java NIO中有很多类和组件,包括Channel,Buffer 和 Selector 构成了核心的API.其它组件如Pipe和FileLock是与三个核心组件共同使用 ...
- Java NIO与IO
当学习了Java NIO和IO的API后,一个问题立即涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们怎样影响您的代 ...
随机推荐
- T3054 高精度练习-文件操作 codevs
http://codevs.cn/problem/3054/ 题目描述 Description 输入一组数据,将每个数据加1后输出 输入描述 Input Description 输入数据:两行,第 ...
- Chrome查看同步状态
最近Hosts不太稳定,翻出去之后安装了一些插件,那么会面临一些问题,比如插件是否已经同步成功,其它PC能否获取等等. 下面是一些查询同步状态的入口: https://www.google.com/s ...
- Vue.js组件的通信之子组件向父组件的通信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【IntelliJ IDEA】2017.3.4版本永久破解
[本版本软件包和破解jar在网盘上有 我的网盘--技术--idea破解所需要的] 1.idea官网下载 历史版本 选择2017.3.4版本下载 https://www.jetbrains.com ...
- Matlab多项式拟合測试
x=0:0.2:4; %生成等差数列 rnd=rand(1,size(x,2))*5; %生成一组随机数 y=x.*x.*x+x.*x+6+rnd; %生成y=x^3+x^2+6函数在垂直方向5个尺度 ...
- 重新认识一遍JavaScript
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【Jqurey EasyUI+Asp.net】----DataGrid数据绑定,以及增、删、改(SQL)
也懒得打其他字了,直接进入主题吧 1.首先,数据表Rex_Test ID int 自增 tName varchar(10) 姓名 tEmail varchar(80) 邮箱 2.至于代码里的Jqure ...
- 【转载】分布式RPC框架性能大比拼
dubbo.motan.rpcx.gRPC.thrift的性能比较 Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 ...
- 【转载】Http协议与TCP协议简单理解后续
写了这么长时间的代码,发现自己对TCP/IP了解的并不是很透彻.虽然会用C#的HttpClient类来进行网络编程,也可以使用Chrome的开发者工具来检测每一次的HTTP请求的报文头与报文体,也知道 ...
- HDU 2018 母牛的故事 [补]
今天刚考完试,和杨曙光玩了RPG,实在不想看题了 /***************************************************/ 母牛的故事 Time Limit: 200 ...