Java優(yōu)化性能技巧集錦(中)
發(fā)表時(shí)間:2024-01-21 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]二、J2EE篇 前面介紹的改善性能技巧適合于大多數(shù)Java應(yīng)用,接下來(lái)要討論的問(wèn)題適合于使用JSP、EJB或JDBC的應(yīng)用。 2.1 使用緩沖標(biāo)記 一些應(yīng)用服務(wù)器加入了面向JSP的緩沖標(biāo)記功能。例如,BEA的WebLogic Server從6.0版本開(kāi)始支持這個(gè)功能,Open Symp...
二、J2EE篇
前面介紹的改善性能技巧適合于大多數(shù)Java應(yīng)用,接下來(lái)要討論的問(wèn)題適合于使用JSP、EJB或JDBC的應(yīng)用。
2.1 使用緩沖標(biāo)記 一些應(yīng)用服務(wù)器加入了面向JSP的緩沖標(biāo)記功能。例如,BEA的WebLogic Server從6.0版本開(kāi)始支持這個(gè)功能,Open Symphony工程也同樣支持這個(gè)功能。JSP緩沖標(biāo)記既能夠緩沖頁(yè)面片斷,也能夠緩沖整個(gè)頁(yè)面。當(dāng)JSP頁(yè)面執(zhí)行時(shí),如果目標(biāo)片斷已經(jīng)在緩沖之中,則生成該片斷的代碼就不用再執(zhí)行。頁(yè)面級(jí)緩沖捕獲對(duì)指定URL的請(qǐng)求,并緩沖整個(gè)結(jié)果頁(yè)面。對(duì)于購(gòu)物籃、目錄以及門戶網(wǎng)站的主頁(yè)來(lái)說(shuō),這個(gè)功能極其有用。對(duì)于這類應(yīng)用,頁(yè)面級(jí)緩沖能夠保存頁(yè)面執(zhí)行的結(jié)果,供后繼請(qǐng)求使用。
對(duì)于代碼邏輯復(fù)雜的頁(yè)面,利用緩沖標(biāo)記提高性能的效果比較明顯;反之,效果可能略遜一籌。
請(qǐng)參見(jiàn)《用緩沖技術(shù)提高JSP應(yīng)用的性能和穩(wěn)定性》。
2.2 始終通過(guò)會(huì)話Bean訪問(wèn)實(shí)體Bean 直接訪問(wèn)實(shí)體Bean不利于性能。當(dāng)客戶程序遠(yuǎn)程訪問(wèn)實(shí)體Bean時(shí),每一個(gè)get方法都是一個(gè)遠(yuǎn)程調(diào)用。訪問(wèn)實(shí)體Bean的會(huì)話Bean是本地的,能夠把所有數(shù)據(jù)組織成一個(gè)結(jié)構(gòu),然后返回它的值。
用會(huì)話Bean封裝對(duì)實(shí)體Bean的訪問(wèn)能夠改進(jìn)事務(wù)管理,因?yàn)闀?huì)話Bean只有在到達(dá)事務(wù)邊界時(shí)才會(huì)提交。每一個(gè)對(duì)get方法的直接調(diào)用產(chǎn)生一個(gè)事務(wù),容器將在每一個(gè)實(shí)體Bean的事務(wù)之后執(zhí)行一個(gè)“裝入-讀取”操作。
一些時(shí)候,使用實(shí)體Bean會(huì)導(dǎo)致程序性能不佳。如果實(shí)體Bean的唯一用途就是提取和更新數(shù)據(jù),改成在會(huì)話Bean之內(nèi)利用JDBC訪問(wèn)數(shù)據(jù)庫(kù)可以得到更好的性能。
2.3 選擇合適的引用機(jī)制 在典型的JSP應(yīng)用系統(tǒng)中,頁(yè)頭、頁(yè)腳部分往往被抽取出來(lái),然后根據(jù)需要引入頁(yè)頭、頁(yè)腳。當(dāng)前,在JSP頁(yè)面中引入外部資源的方法主要有兩種:include指令,以及include動(dòng)作。
include指令:例如。該指令在編譯時(shí)引入指定的資源。在編譯之前,帶有include指令的頁(yè)面和指定的資源被合并成一個(gè)文件。被引用的外部資源在編譯時(shí)就確定,比運(yùn)行時(shí)才確定資源更高效。
include動(dòng)作:例如。該動(dòng)作引入指定頁(yè)面執(zhí)行后生成的結(jié)果。由于它在運(yùn)行時(shí)完成,因此對(duì)輸出結(jié)果的控制更加靈活。但時(shí),只有當(dāng)被引用的內(nèi)容頻繁地改變時(shí),或者在對(duì)主頁(yè)面的請(qǐng)求沒(méi)有出現(xiàn)之前,被引用的頁(yè)面無(wú)法確定時(shí),使用include動(dòng)作才合算。
2.4 在部署描述器中設(shè)置只讀屬性 實(shí)體Bean的部署描述器允許把所有g(shù)et方法設(shè)置成“只讀”。當(dāng)某個(gè)事務(wù)單元的工作只包含執(zhí)行讀取操作的方法時(shí),設(shè)置只讀屬性有利于提高性能,因?yàn)槿萜鞑槐卦賵?zhí)行存儲(chǔ)操作。
2.5 緩沖對(duì)EJB Home的訪問(wèn) EJB Home接口通過(guò)JNDI名稱查找獲得。這個(gè)操作需要相當(dāng)可觀的開(kāi)銷。JNDI查找最好放入Servlet的init()方法里面。如果應(yīng)用中多處頻繁地出現(xiàn)EJB訪問(wèn),最好創(chuàng)建一個(gè)EJBHomeCache類。EJBHomeCache類一般應(yīng)該作為singleton實(shí)現(xiàn)。
2.6 為EJB實(shí)現(xiàn)本地接口 本地接口是EJB 2.0規(guī)范新增的內(nèi)容,它使得Bean能夠避免遠(yuǎn)程調(diào)用的開(kāi)銷。請(qǐng)考慮下面的代碼。
PayBeanHome home = (PayBeanHome)
javax.rmi.PortableRemoteObject.narrow
(ctx.lookup ("PayBeanHome"), PayBeanHome.class);
PayBean bean = (PayBean)
javax.rmi.PortableRemoteObject.narrow
(home.create(), PayBean.class);
第一個(gè)語(yǔ)句表示我們要尋找Bean的Home接口。這個(gè)查找通過(guò)JNDI進(jìn)行,它是一個(gè)RMI調(diào)用。然后,我們定位遠(yuǎn)程對(duì)象,返回代理引用,這也是一個(gè)RMI調(diào)用。第二個(gè)語(yǔ)句示范了如何創(chuàng)建一個(gè)實(shí)例,涉及了創(chuàng)建IIOP請(qǐng)求并在網(wǎng)絡(luò)上傳輸請(qǐng)求的stub程序,它也是一個(gè)RMI調(diào)用。
要實(shí)現(xiàn)本地接口,我們必須作如下修改:
方法不能再拋出java.rmi.RemoteException異常,包括從RemoteException派生的異常,比如TransactionRequiredException、TransactionRolledBackException和NoSuchObjectException。EJB提供了等價(jià)的本地異常,如TransactionRequiredLocalException、TransactionRolledBackLocalException和NoSuchObjectLocalException。
所有數(shù)據(jù)和返回值都通過(guò)引用的方式傳遞,而不是傳遞值。
本地接口必須在EJB部署的機(jī)器上使用。簡(jiǎn)而言之,客戶程序和提供服務(wù)的組件必須在同一個(gè)JVM上運(yùn)行。
如果Bean實(shí)現(xiàn)了本地接口,則其引用不可串行化。
請(qǐng)參見(jiàn)《用本地引用提高EJB訪問(wèn)效率》。