<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    java nio的一個嚴重BUG

    Posted on 2009-09-28 19:27 dennis 閱讀(12796) 評論(9)  編輯  收藏 所屬分類: java源碼解讀
        這個BUG會在linux上導致cpu 100%,使得nio server/client不可用,具體的詳情可以看這里http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6403933 。令人失望的是這個BUG直到jdk 6u4才解決,sun的拖沓讓人難以相信。這個BUG在server端容易出現,因為server端有頻繁地接入斷開連接。
       
        使用jdk 6u4之前版本的nio框架都有這個隱患,除非你的框架很好地處理了這個可能的隱患。Grizzly的處理方式比較簡單,也就是BUG報告里面提到的方式,在SelectionKey.cancel()之后馬上進行了一次select調用將fd從poll(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可能導致的問題。Mina和Netty沒有看到有處理這個BUG的代碼,如果我看錯了,請留言告訴我。Yanf4j一直采用的是grizzly的方式,準備加上jetty的處理方案。當然,最簡單的方案就是升級你的JDK :D


    評論

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2009-09-28 19:59 by lizongbo
    nio還有幾個嚴重的bug,在實際運行中碰到了,sun在u18才修復,而現在u18還沒正式發布。

    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

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2009-09-28 20:19 by dennis
    @lizongbo

    看到了,6u3這個版本似乎問題多多。
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6670302 這個BUG跟我這里描述的相似,解決的方法也是一樣。

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2009-09-28 20:49 by dennis
    http://bugs.sun.com/view_bug.do?bug_id=6693490 這個BUG,一個間接影響也是關閉的channel一直有ready事件,select不阻塞并立即返回0,也就是導致CPU 100%,同樣也是可以通過這里描述的方案解決的。

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2009-09-29 21:32 by 喜樂遞
    最簡單的方案就是升級你的JDK

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2012-05-09 16:54 by hengyunabc
    原來是nio的bug。。
    以前也遇到過,在windows下測試了好久的程序,到linux下就出問題了,cpu跑滿。
    結果我是用每次select都用最新的SelectionKey來替換以前的SelectionKey,貌似沒再出現cpu跑滿的情況。

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2014-11-26 02:32 by kennykinte
    Netty 3.6有處理。

    org.jboss.netty.channel.socket.nio.NioSelector

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2015-08-04 17:27 by 接口科技局
    解決

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2015-08-04 17:27 by 接口科技局
    nio一直都不穩定,說明這個技術還是存在很大漏洞的

    # re: java nio的一個嚴重BUG  回復  更多評論   

    2015-08-04 17:32 by 科技局
    nio技術只能在貼近底層情況去做優化才能解決bug問題,
    如果只是不停修bug,那根本問題還是沒解決
    主站蜘蛛池模板: 黄人成a动漫片免费网站| 国产亚洲情侣久久精品| 国产一级a毛一级a看免费人娇| 亚洲第一成人影院| 乱淫片免费影院观看| 亚洲欧洲日产国码一级毛片 | 一级做a爰片性色毛片免费网站| 免费乱码中文字幕网站| 18禁亚洲深夜福利人口| 亚洲第一区在线观看| 巨胸喷奶水www永久免费| 久久精品国产亚洲av麻| 久久久久国产免费| 亚洲成人免费网址| 美女黄网站人色视频免费国产| 亚洲av成本人无码网站| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 免费无码又黄又爽又刺激| 亚洲国产成人无码AV在线| 可以免费观看的一级毛片| A级毛片成人网站免费看| 久久精品国产亚洲av麻豆| 成人免费一级毛片在线播放视频| 亚洲日韩一区二区一无码| 亚洲国产精品成人久久蜜臀| a级毛片毛片免费观看久潮喷| 亚洲电影免费在线观看| 最近免费中文字幕视频高清在线看| 日本亚洲高清乱码中文在线观看| 亚洲免费无码在线| 精品一区二区三区免费毛片爱| 亚洲乱亚洲乱妇24p| 国产亚洲精品无码拍拍拍色欲 | 青柠影视在线观看免费高清| 亚洲精品成人久久| 国产精品二区三区免费播放心| 国产无遮挡又黄又爽免费网站| 精品日韩亚洲AV无码| 免费v片在线观看无遮挡| 全免费a级毛片免费看| 亚洲AV无码专区在线观看成人|