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

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

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

    Sky's blog

    我和我追逐的夢(mèng)

    常用鏈接

    統(tǒng)計(jì)

    其他鏈接

    友情鏈接

    最新評(píng)論

    編碼最佳實(shí)踐(3)--盡量重用昂貴的初始化對(duì)象

        這里將要講述的是一系列的類似案例,都是在各個(gè)產(chǎn)品進(jìn)行performance tuning時(shí)被發(fā)現(xiàn)的,非常具有普適性。可以說在日常開發(fā)中,有非常大的概率遇到相同或者類似的情形,因此需要對(duì)其保持警惕以便避免陷入類似的性能問題。 
        我們從JAXBContext這個(gè)對(duì)象開始,JAXBContext 是JAXB API的入口,典型的代碼實(shí)現(xiàn)如下: 
        
    private void unmarshal() {  
        JAXBContext context = JAXBContext.newInstance(DirectoryConstants.JAXB_CONTEXT_CLASS);  
        Unmarshaller u = context.createUnmarshaller();  
        Object obj = u.unmarshall(...);  
    }  
        這個(gè)是標(biāo)準(zhǔn)使用流程了,首先初始化JAXBContext對(duì)象,通過JAXBContext對(duì)象創(chuàng)建Unmarshaller對(duì)象,然后使用Unmarshaller對(duì)象來進(jìn)行unmarshal操作。 
        這個(gè)寫法在功能實(shí)現(xiàn)上沒有任何問題,但是如果一旦進(jìn)行壓力測試,就會(huì)暴露性能問題。JAXBContext對(duì)象的初始化是個(gè)資源消耗非常大的操作,我們可以通過threaddump進(jìn)行分析,會(huì)發(fā)現(xiàn)很多工作線程都在執(zhí)行JAXBContext.newInstance()這個(gè)方法,而不是我們期待的u.unmarshal()。而事實(shí)上JAXBContext對(duì)象的Sun實(shí)現(xiàn)是線程安全的,即容許多線程同時(shí)調(diào)用一個(gè)JAXBContext對(duì)象的createUnmarshaller(),因此完全沒有必要為每個(gè)xml的 marshaling 和 unmarshalling 操作去初始化一次JAXBContext對(duì)象。可以參考這里的說明:https://jaxb.dev.java.net/faq/index.html#threadSafety 
        簡單點(diǎn)說,這個(gè)一個(gè)初始化代價(jià)昂貴,卻又可重復(fù)使用的對(duì)象。 
        因此,我們只需要初始化JAXBContext對(duì)象一次并保存起來,然后重復(fù)使用這個(gè)JAXBContext對(duì)象即可。保存JAXBContext對(duì)象的方式可以有很多種,比如cache / threadlocal,或者使用一個(gè)單例來維持這個(gè)對(duì)象。比如下面的代碼示例: 
    private void unmarshal() {  
        JAXBContext context = JAXBContextHolder.get();  
        ...
    }  
      
    public class JAXBContextHolder {  
        private static final JAXBContext instance = JAXBContext.newInstance(DirectoryConstants.JAXB_CONTEXT_CLASS);  
     
        public static JAXBContext get() {  
            return instance;  
        }  
    }  
        在實(shí)際項(xiàng)目中, 通過上面的簡單改進(jìn)之后,我們當(dāng)時(shí)得到了一個(gè)非常巨大的回報(bào):TPS (transactions per second 每秒事務(wù)處理量)直接*3 !! 
        這個(gè)案例從技術(shù)上講非常的簡單,道理很淺顯,相信每個(gè)人都能輕松理解。或者說,這是一個(gè)“知道了就簡單,不知道就容易犯錯(cuò)而不自知”的地方,因此依然有些東西需要注意: 
    (1) 有哪些對(duì)象有類似的特性 
        目前發(fā)現(xiàn)的類似對(duì)象有 
        1. 剛剛上面講到的JAXB API中的 JAXBContext 對(duì)象 
        2. SOAP API中的javax.xml.soap.SOAPFactory 
        3. CFX client 
        通常情況下,在使用各種api或者工具類庫時(shí),如果發(fā)現(xiàn)調(diào)用代碼中有類似的初始化語句,都應(yīng)該稍加注意(除非明確當(dāng)前代碼對(duì)性能完全沒有要求),可以去查一下這個(gè)類對(duì)象的javdoc或者直接看源碼,如果發(fā)現(xiàn)滿足上面所說的特性,則應(yīng)該考慮進(jìn)行上述的性能優(yōu)化。 
        根據(jù)經(jīng)驗(yàn),類似的初始化對(duì)象通常的命名規(guī)則都是***Context/***Factory之類,或者***client,遇到類似名字時(shí)需要提高警惕。 
    (2)假設(shè)問題已經(jīng)存在,如果才能在performance tuning中迅速發(fā)現(xiàn)問題的代碼? 
        通常的辦法就是用thread dump,一般連續(xù)dump個(gè)3-5次,然后通過分析thread dump信息 (推薦使用eclipse插件 lockness),看當(dāng)前請(qǐng)求的線程(通常是一個(gè)線程池)都在干什么。一般初始化昂貴都昂貴在類似文件IO操作或者加鎖之類的地方,很容易在thread dump中被發(fā)現(xiàn)。 

    posted on 2012-06-17 23:02 sky ao 閱讀(2701) 評(píng)論(0)  編輯  收藏 所屬分類: java

    主站蜘蛛池模板: 99蜜桃在线观看免费视频网站| 亚洲电影中文字幕| 国产在线观看麻豆91精品免费| 久久精品免费大片国产大片 | 国产精品亚洲av色欲三区| 精品亚洲国产成AV人片传媒| 最新国产AV无码专区亚洲| 日韩免费一级毛片| 免费国产作爱视频网站| 最近免费mv在线电影| 两个人看www免费视频| 一本到卡二卡三卡免费高| 国产成人精品亚洲一区| 亚洲色中文字幕在线播放| 亚洲日本在线免费观看| 亚洲麻豆精品果冻传媒| 亚洲va在线va天堂va不卡下载| 亚洲人成网站在线观看播放| 亚洲美女高清一区二区三区 | 亚洲视频在线一区二区三区| 亚洲爆乳无码专区| 亚洲日韩精品一区二区三区| 国产成人麻豆亚洲综合无码精品| 亚洲va中文字幕无码| 亚洲不卡AV影片在线播放| 亚洲成?Ⅴ人在线观看无码| 亚洲av日韩av欧v在线天堂| 免费v片视频在线观看视频| 国产一区二区三区在线免费观看 | 2020亚洲男人天堂精品| 精品亚洲AV无码一区二区| 亚洲国产精品一区二区久| 亚洲区精品久久一区二区三区| 亚洲精品第五页中文字幕| 亚洲欧洲精品视频在线观看| 亚洲精品白色在线发布| 亚洲一区二区三区在线| 男人天堂2018亚洲男人天堂| 亚洲乱亚洲乱妇24p| 午夜亚洲国产理论片二级港台二级 | 美女露100%胸无遮挡免费观看|