`
david.org
  • 浏览: 155153 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java nio的一个严重BUG

阅读更多

 

 

这个BUG会在linux上导致cpu 100%,使得nio server/client不可用,具体的详情可以看这里http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6403933 。令人失望的是这个BUG直到jdk 6u4才解决,sun的拖沓让人难以相信。这个BUGserver端容易出现,因为server端有频繁地接入断开连接。 使用jdk 6u4之前版本的nio框架都有这个隐患,除非你的框架很好地处理了这个可能的隐患。Grizzly的处理方式比较简单,也就是BUG报告里面提到的方式,在SelectionKey.cancel()之后马上进行了一次select调用将fdpoll(epoll)中移除:

 

this.selectionKey.cancel();
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上。

 

 

long before=now;
                    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可能导致的问题。MinaNetty没有看到有处理这个BUG的代码,如果我看错了,请留言告诉我。Yanf4j一直采用的是grizzly的方式,准备加上jetty的处理方案。当然,最简单的方案就是升级你的JDK。

 

俺实际上被这个BUG害的很惨, 因为降到了jdk 6u4 CPU仍然会时不时的增高, 原因是低版本的Jetty同样在这方面处理的不是很合理. Jetty关于这个BUG的描述http://jira.codehaus.org/browse/JETTY-937JETTY做为应用, JETTY1.6.22 + JDK 6U4俺现在测下来, CPU基本正常.

 

分享到:
评论
1 楼 nbaertuo 2012-10-09  
现在使用jetty 7.0.0.M2的时候,出现了这个问题,是不是升级jetty就可以了?

相关推荐

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...

    Java NIO英文高清原版

    Java NIO英文高清原版

    java nio 包读取超大数据文件

    Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO 中文版

    讲解了 JavaIO 与 JAVA NIO区别,JAVA NIO设计理念,以及JDK中java NIO中语法的使用

    java nio 实现socket

    java nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socket

    java nio中文版

    java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...

    Java Nio selector例程

    java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...

    一个java NIO的例子

    一个java NIO的例子 有很详细的每一步的描述,很好去理解

    java NIO.zip

    java NIO.zip

    java基于NIO实现Reactor模型源码.zip

    java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...

    java nio 读文件

    java nio 读文件,java nio 读文件

    java NIO技巧及原理

    java NIO技巧及原理解析,java IO原理,NIO框架分析,性能比较

    java nio入门学习,两个pdf

    java nio入门学习,两个pdfjava nio入门学习,两个pdf

    JAVA NIO 学习资料

    JAVA NIO学习资料JAVA NIO学习资料

    Java NIO系列教程(一) Java NIO 概述

    Java NIO系列教程(一) Java NIO 概述

    Java NIO测试示例

    Java NIO测试示例

    基于Java NIO实现五子棋游戏.zip

    基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现...

Global site tag (gtag.js) - Google Analytics