版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、.1. 底層篇1.1. 基本數(shù)據(jù)類型時間分析int的運(yùn)算速度最快,short次之,byte再次之,long再次之。float和double運(yùn)算速度最慢。除法比乘法慢的太多,基本上除法是乘法的9倍時間。當(dāng)然,除了浮點型外。根據(jù)intel cpu的參考數(shù)據(jù),乘法計算時間是移位運(yùn)算的4-5倍是比較正常的。long類型的計算很慢,建議一般少使用它。double運(yùn)算速度和float相當(dāng);浮點的乘法比除法要慢。但是,這個結(jié)果并不能真正說明問題。這個結(jié)果只是一個一般性的,在特殊情況下,乘法還是比除法快,比如:floata * floatb 仍然是比floata / (1/floatb)快。從實際的數(shù)據(jù)結(jié)果來
2、講,乘法的時候,乘數(shù)越小速度越快,特別是在乘數(shù)比3小的時候,乘法時耗接近20,大于4的時候,幾乎都是600的時耗。除法恰好相反,除數(shù)大于1的時候,時耗一般都是350,可是,當(dāng)除數(shù)小于1的時候,時耗就變成了700了。對于大家關(guān)心的移位和乘除2的問題,jdk5.0已經(jīng)做了部分處理。即“var *=2”和“var =1”耗費一樣。但是,除法并沒有進(jìn)行這類處理,即“var /= 2”耗費和基本的除法一樣。1.2. 類和接口調(diào)用時間分析1.2.1. 類的創(chuàng)建 雖然面向?qū)ο笏枷胍呀?jīng)深入人心,但他在帶來快捷方面的編程風(fēng)格的時候,也帶來了低下的效率。在java中,反應(yīng)最快的是object類(這也是顯然的),建
3、立一個新的object類時耗僅僅為20單位。而一個空類(即沒有聲明任何methods和fields)的建立時間則增加到了驚人的400單位。如果再給類增加一些字段的話,時間耗費并沒有特別大的增加,每增加一個int類型字段大概增加30個單位。僅僅就創(chuàng)建時間來說,內(nèi)嵌的類型都有不錯的表現(xiàn)。比如,創(chuàng)建一個int數(shù)組(僅僅包含一個元素)的時間只比創(chuàng)建一個object對象的時間多一倍。當(dāng)然,如果你創(chuàng)建的數(shù)組對象包含1000個元素的話,其創(chuàng)建時間顯然還會加上內(nèi)存管理的時間了,它的時間大概是1萬個時間單位。請注意,我們這里討論的時間單位其實十分小,1萬個時間單位也僅僅只是有0.006毫秒(0.000006秒)
4、。創(chuàng)建一個byte、short、int、long、float和double數(shù)組對象的時間消耗幾乎是一樣的。1.2.2. 方法的調(diào)用java在這個方面有一點做得很好,就是調(diào)用一個只有很少量代碼的方法的時耗和直接把這段代碼寫到本地的時耗相差很小。當(dāng)然不包括需要分配很多本地變量的情況。調(diào)用本類(this指針)的方法是最快的,時間在1-2個單位。調(diào)用其它類的靜態(tài)方法也很快,速度和調(diào)用本來方法差不多。調(diào)用其它類的非靜態(tài)方法速度就慢一些,在1.5-2.5個時間單位之間。調(diào)用繼承接口的方法是十分緩慢的,是調(diào)用普通方法的3倍。但是,如果在實現(xiàn)接口的時候加上final關(guān)鍵字的話,調(diào)用這個方法的時耗就和普通方法差
5、不多了。最慢的是已經(jīng)同步化了的方法。即加上了synchronized關(guān)鍵字的方法。調(diào)用它的時耗比普通方法高出了近20倍。如果不是萬不得已,不要把synchronized加到方法上面,實在不行的話,你可以把它加到代碼塊上去,這種加法比直接加到方法上面快一點。注意,因為方法大部分時候都是完成很多事情的,所以,十分注意調(diào)用方法的開銷是沒有必要的,因為這個時間和方法執(zhí)行需要的時間比較起來只是毛毛雨。1.3. 基本操作時間耗費2. 通用篇“通用篇”討論的問題適合于大多數(shù)java應(yīng)用。2.1. 不用new關(guān)鍵詞創(chuàng)建類的實例用new關(guān)鍵詞創(chuàng)建類的實例時,構(gòu)造函數(shù)鏈中的所有構(gòu)造函數(shù)都會被自動調(diào)用。但如果一個對
6、象實現(xiàn)了cloneable接口,我們可以調(diào)用它的clone()方法。clone()方法不會調(diào)用任何類構(gòu)造函數(shù)。在使用設(shè)計模式(design pattern)的場合,如果用factory模式創(chuàng)建對象,則改用clone()方法創(chuàng)建新的對象實例非常簡單。例如,下面是factory模式的一個典型實現(xiàn):public static credit getnewcredit() return new credit();改進(jìn)后的代碼使用clone()方法,如下所示:private static credit basecredit = new credit();public static credit getne
7、wcredit() return (credit) basecredit.clone();上面的思路對于數(shù)組處理同樣很有用。2.2. 使用非阻塞i/o版本較低的jdk不支持非阻塞i/o api。為避免i/o阻塞,一些應(yīng)用采用了創(chuàng)建大量線程的辦法(在較好的情況下,會使用一個緩沖池)。這種技術(shù)可以在許多必須支持并發(fā)i/o流的應(yīng)用中見到,如web服務(wù)器、報價和拍賣應(yīng)用等。然而,創(chuàng)建java線程需要相當(dāng)可觀的開銷。jdk 1.4引入了非阻塞的i/o庫(java.nio)。如果應(yīng)用要求使用版本較早的jdk,在這里有一個支持非阻塞i/o的軟件包。請參見sun中國網(wǎng)站的調(diào)整java的i/o性能。2.3. 慎
8、用異常異常對性能不利。拋出異常首先要創(chuàng)建一個新的對象。throwable接口的構(gòu)造函數(shù)調(diào)用名為fillinstacktrace()的本地(native)方法,fillinstacktrace()方法檢查堆棧,收集調(diào)用跟蹤信息。只要有異常被拋出,vm就必須調(diào)整調(diào)用堆棧,因為在處理過程中創(chuàng)建了一個新的對象。異常只能用于錯誤處理,不應(yīng)該用來控制程序流程。2.4. 不要重復(fù)初始化變量默認(rèn)情況下,調(diào)用類的構(gòu)造函數(shù)時, java會把變量初始化成確定的值:所有的對象被設(shè)置成null,整數(shù)變量(byte、short、int、long)設(shè)置成0,float和 double變量設(shè)置成0.0,邏輯值設(shè)置成false
9、。當(dāng)一個類從另一個類派生時,這一點尤其應(yīng)該注意,因為用new關(guān)鍵詞創(chuàng)建一個對象時,構(gòu)造函數(shù)鏈中的所有構(gòu)造函數(shù)都會被自動調(diào)用。2.5. 盡量使用局部變量調(diào)用方法時傳遞的參數(shù)以及在調(diào)用中創(chuàng)建的臨時變量都保存在棧(stack)中,速度較快。其他變量,如靜態(tài)變量、實例變量等,都在堆(heap)中創(chuàng)建,速度較慢。另外,依賴于具體的編譯器/jvm,局部變量還可能得到進(jìn)一步優(yōu)化。請參見盡可能使用堆棧變量。2.6. 位移完成乘法和除法考慮下面的代碼:for (val = 0; val 100000; val +=5) alterx = val * 8; myresult = val * 2; 用移位操作替代乘
10、法操作可以極大地提高性能。下面是修改后的代碼:for (val = 0; val 100000; val += 5) alterx = val 3; myresult = val 1; 修改后的代碼不再做乘以8的操作,而是改用等價的左移3位操作,每左移1位相當(dāng)于乘以2。相應(yīng)地,右移1位操作相當(dāng)于除以2。值得一提的是,雖然移位操作速度快,但可能使代碼比較難于理解,所以最好加上一些注釋。2.7. 避免在循環(huán)體中創(chuàng)建對象,即使該對象占用內(nèi)存空間不大.for(int i=0;i10000;+i) object obj = new object(); system.out.println(obj=+ob
11、j); 應(yīng)改成object obj = null; for(int i=0;i10000;+i) obj = new object(); system.out.println(obj=+obj); 2.8. 當(dāng)做數(shù)組拷貝操作時,采用system.arraycopy()方法2.9. 盡量避免在循環(huán)體中調(diào)用方法2.10. 盡量避免在循環(huán)體中使用try-catch 塊2.11. 在多重循環(huán)中,如果有可能,盡量將最長的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層,以減少循環(huán)層間的變換次數(shù)2.12. 如果預(yù)知長度,就設(shè)置arraylist的長度2.13. 避免在類在構(gòu)造器的初始化其他類2.14. 盡量避免在構(gòu)造
12、中對靜態(tài)變量做賦值操作2.15. 不要在類的構(gòu)造器中創(chuàng)建類的實例3. jsp/servlet篇3.1. 采用out 對象中的print方法代替println()方法3.2. 采用適當(dāng)?shù)闹党跏蓟痮ut 對象緩沖區(qū)的大小3.3. 盡量采用forward()方法重定向新的jsp3.4. 通過init()方法來緩存一些靜態(tài)數(shù)據(jù)以提高應(yīng)用性能.3.5. servletoutputstream 取代 printwriter4. db篇4.1. 純jdbc最快4.2. 最重要的是盡量減少與數(shù)據(jù)庫通信的次數(shù),多使用批處理4.3. 設(shè)置合適的fetch_size和batch_size4.4. 采用連接池技術(shù)4.
13、5. 選擇合適的事務(wù)隔離層與及時關(guān)閉連接對象4.6. preparedstatement防止sql注入4.7. 盡可能地做批處理更新5. 內(nèi)存篇5.1. 別用new boolean()在很多場景中boolean類型是必須的,比如jdbc中boolean類型的set與get都是通過boolean封裝傳遞的,大部分orm也是用boolean來封裝boolean類型的,比如:ps.setboolean(isclosed,new boolean(true);ps.setboolean(isclosed,new boolean(isclosed);ps.setboolean(isclosed,new b
14、oolean(i=3);通常這些系統(tǒng)中構(gòu)造的boolean實例的個數(shù)是相當(dāng)多的,所以系統(tǒng)中充滿了大量boolean實例小對象,這是相當(dāng)消耗內(nèi)存的。boolean類實際上只要兩個實例就夠了,一個true的實例,一個false的實例。boolean類提供兩了個靜態(tài)變量:public static final boolean true = new boolean(true);public static final boolean false = new boolean(false);需要的時候只要取這兩個變量就可以了,比如:ps.setboolean(isclosed,boolean.true);那
15、么象2、3句那樣要根據(jù)一個boolean變量來創(chuàng)建一個boolean怎么辦呢?可以使用boolean提供的靜態(tài)方法: boolean.valueof()比如:ps.setboolean(isclosed,boolean.valueof(isclosed);ps.setboolean(isclosed,boolean.valueof(i=3);因為valueof的內(nèi)部實現(xiàn)是:return (b ? true : false);所以可以節(jié)省大量內(nèi)存。相信如果java規(guī)范直接把boolean的構(gòu)造函數(shù)規(guī)定成private,就再也不會出現(xiàn)這種情況了。5.2. 別用new integer 和boolea
16、n類似,java開發(fā)中使用integer封裝int的場合也非常多,并且通常用int表示的數(shù)值通常都非常小。sun sdk中對integer的實例化進(jìn)行了優(yōu)化,integer類緩存了-128到127這256個狀態(tài)的integer,如果使用integer.valueof(int i),傳入的int范圍正好在此內(nèi),就返回靜態(tài)實例。這樣如果我們使用integer.valueof代替new integer的話也將大大降低內(nèi)存的占用。如果您的系統(tǒng)要在不同的sdk(比如ibm sdk)中使用的話,那么可以自己做了工具類封裝一下,比如integerutils.valueof(),這樣就可以在任何sdk中都可以
17、使用這種特性。5.3. 用stringbuffer代替字符串相加這個我就不多講了,因為已經(jīng)被人講過n次了。我只想將一個不是笑話的笑話,我在看國內(nèi)某“著名”java開發(fā)的web系統(tǒng)的源碼中,竟然發(fā)現(xiàn)其中大量的使用字符串相加,一個拼裝sql語句的方法中竟然最多構(gòu)造了將近100個string實例。無語中!5.4. 過濫使用哈希表有一定開發(fā)經(jīng)驗的開發(fā)人員經(jīng)常會使用hash表(hash表在jdk中的一個實現(xiàn)就是hashmap)來緩存一些數(shù)據(jù),從而提高系統(tǒng)的運(yùn)行速度。比如使用hashmap緩存一些物料信息、人員信息等基礎(chǔ)資料,這在提高系統(tǒng)速度的同時也加大了系統(tǒng)的內(nèi)存占用,特別是當(dāng)緩存的資料比較多的時候。其
18、實我們可以使用操作系統(tǒng)中的緩存的概念來解決這個問題,也就是給被緩存的分配一個一定大小的緩存容器,按照一定的算法淘汰不需要繼續(xù)緩存的對象,這樣一方面會因為進(jìn)行了對象緩存而提高了系統(tǒng)的運(yùn)行效率,同時由于緩存容器不是無限制擴(kuò)大,從而也減少了系統(tǒng)的內(nèi)存占用?,F(xiàn)在有很多開源的緩存實現(xiàn)項目,比如ehcache、oscache等,這些項目都實現(xiàn)了fifo、mru等常見的緩存算法。5.5. 避免過深的類層次結(jié)構(gòu)和過深的方法調(diào)用因為這兩者都是非常占用內(nèi)存的(特別是方法調(diào)用更是堆??臻g的消耗大戶)。5.6. 變量只有在用到它的時候才定義和實例化5.7. 盡量避免使用static變量,類內(nèi)私有常量可以用final來
19、代替6. jvm篇6.1. 內(nèi)存管理java的內(nèi)存管理就是對象的分配和釋放問題。在java中,程序員需要通過關(guān)鍵字new為每個對象申請內(nèi)存空間 (基本類型除外),所有的對象都在堆 (heap)中分配空間。對象的釋放是由gc決定和執(zhí)行的。在java中,內(nèi)存的分配是由程序完成的,而內(nèi)存的釋放是由gc完成的,這種收支兩條線的方法簡化了程序員的工作。但也加重了jvm的工作。這也是java程序運(yùn)行速度較慢的原因之一。6.1.1. gc釋放空間方法監(jiān)控每一個對象的運(yùn)行狀態(tài),包括對象的申請、引用、被引用、賦值等。當(dāng)該對象不再被引用時,釋放對象。6.1.2. 內(nèi)存管理結(jié)構(gòu)java使用有向圖的方式進(jìn)行內(nèi)存管理,
20、對于程序的每一個時刻,我們都有一個有向圖表示jvm的內(nèi)存分配情況。將對象考慮為有向圖的頂點,將引用關(guān)系考慮為圖的有向邊,有向邊從引用者指向被引對象。另外,每個線程對象可以作為一個圖的起始頂點,例如大多程序從main進(jìn)程開始執(zhí)行,那么該圖就是以main進(jìn)程頂點開始的一棵根樹。在這個有向圖中,根頂點可達(dá)的對象都是有效對象,gc將不回收這些對象。如果某個對象 (連通子圖)與這個根頂點不可達(dá)(注意,該圖為有向圖),那么我們認(rèn)為這個(這些)對象不再被引用,可以被gc回收。使用有向圖方式管理內(nèi)存的優(yōu)缺點java使用有向圖的方式進(jìn)行內(nèi)存管理,可以消除引用循環(huán)的問題,例如有三個對象,相互引用,只要它們和根進(jìn)程
21、不可達(dá)的,那么gc也是可以回收它們的。這種方式的優(yōu)點是管理內(nèi)存的精度很高,但是效率較低。另外一種常用的內(nèi)存管理技術(shù)是使用計數(shù)器,例如com模型采用計數(shù)器方式管理構(gòu)件,它與有向圖相比,精度行低(很難處理循環(huán)引用的問題),但執(zhí)行效率很高。6.1.3. java的內(nèi)存泄露java雖然由gc來回收內(nèi)存,但也是存在泄露問題的,只是比c+小一點。c+所有對象的分配和回收都需要由用戶來管理。即需要管理點,也需要管理邊。若存在不可達(dá)的點,無法回收分配給那個點的內(nèi)存,導(dǎo)致內(nèi)存泄露。存在無用的對象引用,自然也會導(dǎo)致內(nèi)存泄露。java由gc來管理內(nèi)存回收,gc將回收不可達(dá)的對象占用的內(nèi)存空間。所以,java需要考慮的內(nèi)存泄露問題主要是那些被引用但無用的對象即指要管理
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國旅居康養(yǎng)行業(yè)全國市場開拓戰(zhàn)略制定與實施研究報告
- 2025-2030年中國小家電行業(yè)商業(yè)模式創(chuàng)新戰(zhàn)略制定與實施研究報告
- 2025-2030年中國壓鑄行業(yè)營銷創(chuàng)新戰(zhàn)略制定與實施研究報告
- 2025-2030年中國汽車經(jīng)銷行業(yè)并購重組擴(kuò)張戰(zhàn)略制定與實施研究報告
- 網(wǎng)絡(luò)工程師工作總結(jié)5篇
- 建設(shè)項目環(huán)境設(shè)施竣工驗收指南
- 面向智能網(wǎng)聯(lián)汽車的成熟駕駛模型白皮書 202311
- 家政培訓(xùn)師知識點課件
- 2023-2029年中國鐵路后行業(yè)發(fā)展監(jiān)測及市場發(fā)展?jié)摿︻A(yù)測報告
- 冷鏈物流園及配套基礎(chǔ)設(shè)施建設(shè)項目資金申請報告
- 寒假彎道超車主題勵志班會課件
- 河北省石家莊市2023-2024學(xué)年高二上學(xué)期期末考試 語文 Word版含答案
- 觸電與應(yīng)急知識培訓(xùn)總結(jié)
- 代理記賬機(jī)構(gòu)自查報告范文
- 項目貸款保證函書
- 新版標(biāo)準(zhǔn)日本語(初級)上下冊單詞默寫表
- 面向5G網(wǎng)絡(luò)建設(shè)的站點供電技術(shù)應(yīng)用與發(fā)展
- 普通語文課程標(biāo)準(zhǔn)(2023年核心素養(yǎng)版)
- 洗滌劑常用原料
- 曼陀羅中毒課件
- (新版)焊工(初級)理論知識考試200題及答案
評論
0/150
提交評論