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

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

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

    一段好玩的測試LinkedBlockingQueue.poll超時(shí)的程序

    在產(chǎn)品中有碰到過使用LinkedBlockingQueue.poll時(shí)超時(shí)很不準(zhǔn)的現(xiàn)象,關(guān)鍵是這不是一般的不準(zhǔn),如果只是一點(diǎn)點(diǎn)不準(zhǔn)的話也就勉強(qiáng)接受了,例如指定poll的超時(shí)時(shí)間為100ms,但最終執(zhí)行.poll這段代碼就花費(fèi)了8000ms的現(xiàn)象,這篇blog就是展示下通過一段小小的代碼來重現(xiàn)這樣的現(xiàn)象,畢竟沒有重現(xiàn)是無法證明為什么會(huì)出現(xiàn)這樣的現(xiàn)象的。

    由于在出現(xiàn)這個(gè)現(xiàn)象的時(shí)候有看到過OutOfMemory的錯(cuò),雖然java進(jìn)程沒退出,但猜想可能是這個(gè)原因造成的,于是寫了下面這段代碼:
    public static void main(String[] args) throws Exception{
            
    long beginTime=System.currentTimeMillis();
            Map
    <String, byte[]> cache=new HashMap<String, byte[]>();
            
    for (int i = 0; i < 1000000; i++) {
                cache.put(String.valueOf(i),
    new byte[500]);
            }
            CountDownLatch latch
    =new CountDownLatch(25);
            
    for (int i = 0; i < 5; i++) {
                
    for (int j = 0; j < 5; j++) {
                    Thread thread
    =new Thread(new TestThread(latch));
                    thread.start();
                }
            }
            latch.await();
            
    long endTime=System.currentTimeMillis();
            System.out.println(
    "總共執(zhí)行時(shí)間:"+(endTime-beginTime));
        }
        
        
    static class TestThread implements Runnable{

            
    private CountDownLatch latch;
            
            
    public TestThread(CountDownLatch latch){
                
    this.latch=latch;
            }
            
            
    public void run(){
                BlockingQueue
    <String> queue=new LinkedBlockingQueue<String>(1);
                
    try{
                    
    for (int i = 0; i < 5; i++) {
                        
    long beginTime=System.currentTimeMillis();
                        queue.poll(
    100, TimeUnit.MILLISECONDS);
                        
    long endTime=System.currentTimeMillis();
                        
    long consumeTime=endTime-beginTime;
                        
    if(consumeTime>200)
                            System.out.println(
    "獲取queue的時(shí)間為:"+consumeTime);
                        @SuppressWarnings(
    "unused")
                        
    byte[] bytesNew=new byte[25506000];
                    }
                }
                
    catch(Exception e){
                    ;
                }
                latch.countDown();
            }
            
        }

    啟動(dòng)上面程序時(shí),將jvm參數(shù)設(shè)置為-Xms640M -Xmx640M,運(yùn)行后,應(yīng)該會(huì)看到有很多queue.poll執(zhí)行超過200ms的現(xiàn)象,甚至?xí)霈F(xiàn)8000ms的現(xiàn)象。

    上面整段程序的寫法就是用大量的小對象占據(jù)old generation,然后啟動(dòng)多個(gè)線程,每個(gè)線程運(yùn)行的時(shí)候new一個(gè)大的對象,讓其產(chǎn)生有可能直接從new generation分配到old generation,從而導(dǎo)致Full GC頻繁執(zhí)行,里面的byte數(shù)組的大小的原則為:塞滿內(nèi)存,產(chǎn)生Full GC,但又盡量不讓應(yīng)用出現(xiàn)OutOfMemory,或者說不出現(xiàn)過于頻繁的OutOfMemory,避免jvm crash。

    從上面程序的運(yùn)行效果來看,當(dāng)jvm內(nèi)存消耗的很嚴(yán)重的情況下,poll的超時(shí)是沒法準(zhǔn)的,其實(shí)分析下原因,還是挺正常的:
    1、jvm內(nèi)存消耗嚴(yán)重的情況下,Minor GC和Full GC瘋狂執(zhí)行,導(dǎo)致了應(yīng)用的執(zhí)行不斷的被暫停,因此當(dāng)線程已經(jīng)進(jìn)入poll等待后,這個(gè)線程沒有機(jī)會(huì)被執(zhí)行,導(dǎo)致當(dāng)其有機(jī)會(huì)執(zhí)行時(shí),早就超過了指定的超時(shí)時(shí)間,因此其超時(shí)不準(zhǔn)并不是本身的機(jī)制導(dǎo)致的,而是jvm GC造成的多次暫停;
    2、多次暫停的情況下,jvm需要不斷的調(diào)度恢復(fù)線程,這需要消耗很多的資源,而且切換多了Swap空間很容易不夠用,最終導(dǎo)致jvm crash。

    posted on 2009-03-12 16:52 BlueDavy 閱讀(7813) 評論(4)  編輯  收藏 所屬分類: Java

    評論

    # re: 一段好玩的測試LinkedBlockingQueue.poll超時(shí)的程序 2009-03-12 20:23 lizongbo

    這個(gè)應(yīng)該和jdk的具體版本有關(guān),不知道你們用的具體哪個(gè)版本的jdk。
    我剛才試了一下用不同版本jdk運(yùn)行的效果:
    各版本的耗時(shí)不一樣:
    1.7.0-nio2 ,基本都在359左右。
    1.6.0_11 ,基本都在453左右。
    1.5.0_14,基本在2359左右。


    前段時(shí)間我們就是因?yàn)閖dk的gc問題,對所有的服務(wù)器都進(jìn)行了jdk升級到j(luò)dk1.6.0_12。

      回復(fù)  更多評論   

    # re: 一段好玩的測試LinkedBlockingQueue.poll超時(shí)的程序 2009-03-12 20:28 lizongbo

    漏了補(bǔ)充說明,只在jdk1.5的時(shí)候運(yùn)行出現(xiàn)了java.lang.OutOfMemoryError,而jdk1.6和jdk1.7都沒出現(xiàn)OutOfMemoryError.
      回復(fù)  更多評論   

    # re: 一段好玩的測試LinkedBlockingQueue.poll超時(shí)的程序 2009-03-12 20:34 BlueDavy

    @lizongbo
    多謝,:),我之前還只在1.5.0_10上跑過,看來越新的java版本,性能確實(shí)越好,呵呵  回復(fù)  更多評論   

    # re: 一段好玩的測試LinkedBlockingQueue.poll超時(shí)的程序 2009-03-12 22:50 岑文初

    觀察過,1.5肯定是不回收的,它的一個(gè)鎖信號量,1.6回收比較慢,要到一定的內(nèi)存占用比例才會(huì)去Gc。SIP最早時(shí)候的內(nèi)存泄露就是這個(gè)問題。  回復(fù)  更多評論   

    公告

     









    feedsky
    抓蝦
    google reader
    鮮果

    導(dǎo)航

    <2009年3月>
    22232425262728
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    統(tǒng)計(jì)

    隨筆分類

    隨筆檔案

    文章檔案

    Blogger's

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲欧洲精品在线| 一级毛片完整版免费播放一区| 成人免费视频一区| 老司机午夜性生免费福利| 亚洲精品字幕在线观看| 国产精品69白浆在线观看免费| 精品久久久久久亚洲中文字幕| 狠狠色婷婷狠狠狠亚洲综合| **aaaaa毛片免费同男同女| 久久久久亚洲精品无码网址色欲 | 成人免费视频试看120秒| 丰满妇女做a级毛片免费观看| 精品日韩亚洲AV无码 | 在线亚洲97se亚洲综合在线| 亚洲精品在线免费观看| 美女18毛片免费视频| 中文字幕亚洲综合久久2| 国产jizzjizz视频全部免费| 啦啦啦完整版免费视频在线观看| 看免费毛片天天看| 亚洲国产午夜精品理论片| 亚洲性久久久影院| 成年女人毛片免费播放人 | 搡女人真爽免费视频大全| 国产在线播放线91免费| 亚洲国产精品无码久久九九大片 | 免费看片在线观看| 中国国语毛片免费观看视频| 亚洲人成电影网站色www| 久久亚洲精精品中文字幕| 国产日韩成人亚洲丁香婷婷| 嫩草视频在线免费观看| 曰批全过程免费视频播放网站 | 亚洲国产午夜精品理论片| 亚洲精品国产精品乱码在线观看| 国产成人精品免费视频大全五级 | 亚洲成av人影院| 亚洲国模精品一区| 日本高清色本免费现在观看| 91免费人成网站在线观看18| 九九美女网站免费|