java代碼重構優(yōu)化經驗 java代碼重構的思路
Java代碼如何優(yōu)化
1. 盡量在合適的場合使用單例
使用單例可以減輕加載的負擔,縮短加載的時間,提高加載的效率,但并不是所有地方都適用于單例,簡單來說,單例主要適用于以下三個方面:
第一,控制資源的使用,通過線程同步來控制資源的并發(fā)訪問;
第二,控制實例的產生,以達到節(jié)約資源的目的;
第三,控制數據共享,在不建立直接關聯(lián)的條件下,讓多個不相關的進程或線程之間實現(xiàn)通信。
2. 盡量避免隨意使用靜態(tài)變量
要知道,當某個對象被定義為stataic變量所引用,那么gc通常是不會回收這個對象所占有的內存
3. 盡量避免過多過常的創(chuàng)建Java對象
盡量避免在經常調用的方法,循環(huán)中new對象,由于系統(tǒng)不僅要花費時間來創(chuàng)建對象,而且還要花時間對這些對象進行垃圾回收和處理,在我們可以控制的范圍內,最大限度的重用對象,最好能用基本的數據類型或數組來替代對象。
4. 盡量使用final修飾符
帶有final修飾符的類是不可派生的。在Java核心API中,有許多應用final的例子,例如java.lang.String.為String類指定final防止了使用者覆蓋length()方法。另外,如果一個類是final的,則該類所有方法都是final的。Java編譯器會尋找機會內聯(lián)(inline)所有的final方法(這和具體的編譯器實現(xiàn)有關)。此舉能夠使性能平均提高50%.
5. 盡量使用局部變量
調用方法時傳遞的參數以及在調用中創(chuàng)建的臨時變量都保存在棧(Stack)中,速度較快。其他變量,如靜態(tài)變量、實例變量等,都在堆(Heap)中創(chuàng)建,速度較慢。
6. 盡量處理好包裝類型和基本類型兩者的使用場所
雖然包裝類型和基本類型在使用過程中是可以相互轉換,但它們兩者所產生的內存區(qū)域是完全不同的,基本類型數據產生和處理都在棧中處理,包裝類型是對象,是在堆中產生實例。
在集合類對象,有對象方面需要的處理適用包裝類型,其他的處理提倡使用基本類型。
7. 慎用synchronized,盡量減小synchronize的方法
都知道,實現(xiàn)同步是要很大的系統(tǒng)開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。synchronize方法被調用時,直接會把當前對象鎖 了,在方法執(zhí)行完之前其他線程無法調用當前對象的其他方法。所以synchronize的方法盡量小,并且應盡量使用方法同步代替代碼塊同步。
8. 盡量使用StringBuilder和StringBuffer進行字符串連接
這個就不多講了。
9. 盡量不要使用finalize方法
實際上,將資源清理放在finalize方法中完成是非常不好的選擇,由于GC的工作量很大,尤其是回收Young代內存時,大都會引起應用程序暫停,所以再選擇使用finalize方法進行資源清理,會導致GC負擔更大,程序運行效率更差。
10. 盡量使用基本數據類型代替對象
String str = "hello";
上面這種方式會創(chuàng)建一個"hello"字符串,而且JVM的字符緩存池還會緩存這個字符串;
String str = new String("hello");
此時程序除創(chuàng)建字符串外,str所引用的String對象底層還包含一個char[]數組,這個char[]數組依次存放了h,e,l,l,o
11. 單線程應盡量使用HashMap、ArrayList
HashTable、Vector等使用了同步機制,降低了性能。
12. 盡量合理的創(chuàng)建HashMap
當你要創(chuàng)建一個比較大的hashMap時,充分利用另一個構造函數
public HashMap(int initialCapacity, float loadFactor)
避免HashMap多次進行了hash重構,擴容是一件很耗費性能的事,在默認中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能準確的估計你所需要的最佳大小,同樣的Hashtable,Vectors也是一樣的道理。
13. 盡量減少對變量的重復計算
并且在循環(huán)中應該避免使用復雜的表達式,在循環(huán)中,循環(huán)條件會被反復計算,如果不使用復雜表達式,而使循環(huán)條件值不變的話,程序將會運行的更快。
14. 盡量避免不必要的創(chuàng)建
15. 盡量在finally塊中釋放資源
程序中使用到的資源應當被釋放,以避免資源泄漏。這最好在finally塊中去做。不管程序執(zhí)行的結果如何,finally塊總是會執(zhí)行的,以確保資源的正確關閉。
16. 盡量使用移位來代替'a/b'的操作
"/"是一個代價很高的操作,使用移位的操作將會更快和更有效
17.盡量使用移位來代替'a*b'的操作
同樣的,對于'*'操作,使用移位的操作將會更快和更有效
18. 盡量確定StringBuffer的容量
StringBuffer 的構造器會創(chuàng)建一個默認大小(通常是16)的字符數組。在使用中,如果超出這個大小,就會重新分配內存,創(chuàng)建一個更大的數組,并將原先的數組復制過來,再 丟棄舊的數組。在大多數情況下,你可以在創(chuàng)建 StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高性能。
19. 盡量早釋放無用對象的引用
大部分時,方法局部引用變量所引用的對象 會隨著方法結束而變成垃圾,因此,大部分時候程序無需將局部,引用變量顯式設為null.
20. 盡量避免使用二維數組
二維數據占用的內存空間比一維數組多得多,大概10倍以上。
21. 盡量避免使用split
除非是必須的,否則應該避免使用split,split由于支持正則表達式,所以效率比較低,如果是頻繁的幾十,幾百萬的調用將會耗費大量資源,如果確實需 要頻繁的調用split,可以考慮使用apache的StringUtils.split(string,char),頻繁split的可以緩存結果。
22. ArrayList LinkedList
一 個是線性表,一個是鏈表,一句話,隨機查詢盡量使用ArrayList,ArrayList優(yōu)于LinkedList,LinkedList還要移動指 針,添加刪除的操作LinkedList優(yōu)于ArrayList,ArrayList還要移動數據,不過這是理論性分析,事實未必如此,重要的是理解好2 者得數據結構,對癥下藥。
23. 盡量使用System.arraycopy ()代替通過來循環(huán)復制數組
System.arraycopy() 要比通過循環(huán)來復制數組快的多
24. 盡量緩存經常使用的對象
盡可能將經常使用的對象進行緩存,可以使用數組,或HashMap的容器來進行緩存,但這種方式可能導致系統(tǒng)占用過多的緩存,性能下降,推薦可以使用一些第三方的開源工具,如EhCache,Oscache進行緩存,他們基本都實現(xiàn)了FIFO/FLU等緩存算法。
25. 盡量避免非常大的內存分配
有時候問題不是由當時的堆狀態(tài)造成的,而是因為分配失敗造成的。分配的內存塊都必須是連續(xù)的,而隨著堆越來越滿,找到較大的連續(xù)塊越來越困難。
26. 慎用異常
當創(chuàng)建一個異常時,需要收集一個棧跟蹤(stack track),這個棧跟蹤用于描述異常是在何處創(chuàng)建的。構建這些棧跟蹤時需要為運行時棧做一份快照,正是這一部分開銷很大。當需要創(chuàng)建一個 Exception 時,JVM 不得不說:先別動,我想就您現(xiàn)在的樣子存一份快照,所以暫時停止入棧和出棧操作。棧跟蹤不只包含運行時棧中的一兩個元素,而是包含這個棧中的每一個元素。
如 果您創(chuàng)建一個 Exception ,就得付出代價。好在捕獲異常開銷不大,因此可以使用 try-catch 將核心內容包起來。從技術上講,您甚至可以隨意地拋出異常,而不用花費很大的代價。招致性能損失的并不是 throw 操作--盡管在沒有預先創(chuàng)建異常的情況下就拋出異常是有點不尋常。真正要花代價的是創(chuàng)建異常。幸運的是,好的編程習慣已教會我們,不應該不管三七二十一就 拋出異常。異常是為異常的情況而設計的,使用時也應該牢記這一原則。
(1)。 用Boolean.valueOf(boolean b)代替new Boolean()
包裝類的內存占用是很恐怖的,它是基本類型內存占用的N倍(N2),同時new一個對象也是性能的消耗。
(2)。 用Integer.valueOf(int i)代替new Integer()
和Boolean類似,java開發(fā)中使用Integer封裝int的場合也非常多,并且通常用int表示的數值都非常小。SUN SDK中對Integer的實例化進行了優(yōu)化,Integer類緩存了-128到127這256個狀態(tài)的Integer,如果使用 Integer.valueOf(int i),傳入的int范圍正好在此內,就返回靜態(tài)實例。這樣如果我們使用Integer.valueOf代替new Integer的話也將大大降低內存的占用。
(3)。 用StringBuffer的append方法代替"+"進行字符串相加。
這個已經被N多人說過N次了,這個就不多說了。
(4)。 避免過深的類層次結構和過深的方法調用。
因為這兩者都是非常占用內存的(特別是方法調用更是堆??臻g的消耗大戶)。
(5)。 變量只有在用到它的時候才定義和實例化。
這是初學者最容易犯的錯,合理的使用變量,并且只有在用到它的時候才定義和實例化,能有效的避免內存空間和執(zhí)行性能上的浪費,從而提高了代碼的效率。
(6)。 避免在循環(huán)體中聲明創(chuàng)建對象,即使該對象占用內存空間不大。
這種情況在我們的實際應用中經常遇到,而且我們很容易犯類似的錯誤
采用上面的第二種編寫方式,僅在內存中保存一份對該對象的引用,而不像上面的第一種編寫方式中代碼會在內存中產生大量的對象引用,浪費大量的內存空間,而且增大了垃圾回收的負荷。因此在循環(huán)體中聲明創(chuàng)建對象的編寫方式應該盡量避免。
(7)。 如果if判斷中多個條件用'||'或者''連接,請將出現(xiàn)頻率最高的條件放在表達式最前面。
這個小技巧往往能有效的提高程序的性能,尤其是當if判斷放在循環(huán)體里面時,效果更明顯。
1.JVM管理兩種類型的內存:堆內存(heap),棧內存(stack),堆內在主要用來存儲程序在運行時創(chuàng)建或實例化的對象與變量。而棧內存則是用來存儲程序代碼中聲明為靜態(tài)(static)(或非靜態(tài))的方法。
2.JVM中對象的生命周期,創(chuàng)建階段,應用階段,不可視階段,不可到達階段,可收集階段,終結階段,釋放階段
3.避免在循環(huán)體中創(chuàng)建對象,即使該對象點用內存空間不大。
4.軟引用的主要特點是具有較強的引用功能。只有當內存不夠的時候,才回收這類內存,因此在內存足夠的時候,它們通常不被回收。它可以用于實現(xiàn)一些常用資源的緩存,實現(xiàn)Cache的功能
5.弱引用對象與Soft引用對象最大不同就在于:GC在進行回收時,需要通過算法檢查是否回收Soft引用對象,而對于Weak引用對象,GC總是進行回收。
6.共享靜態(tài)變量存儲空間
7.有時候我們?yōu)榱颂岣呦到y(tǒng)性能,避免重復耗時的操作,希望能夠重用一些創(chuàng)建完成的對象,利用對象池實現(xiàn)。類似JDBC連接池。
8.瞬間值,序列化對象大變量時,如果此大變量又沒有用途,則使用transient聲明,不序列化此變量。同時網絡傳輸中也不傳輸。
9.不要提前創(chuàng)建對象
10 .(1)最基本的建議就是盡早釋放無用對象的引用
A a = new A();
a = null; //當使用對象a之后主動將其設置為空
(2)盡量少用finalize函數。
(3) 如果需要使用經常用到的圖片展,可以使用軟引用。
(4) 注意集合數據類型,包括數組,樹等數據,這些數據結構對GC來說,回收更為復雜,
(5) 盡量避免在類的默認構造器中創(chuàng)建,初始化大量的對象,防止在調用其自類的構造器時造成不必要的內存資源浪費。
(6) 盡量避免強制系統(tǒng)做垃圾內存回收。
(7) 盡量避免顯式申請數組空間。
(8) 盡量在合適的場景下使用對象池技術以提高系統(tǒng)性能,縮減系統(tǒng)內存開銷。
11.當做數組拷貝操作時,采用System.arraycopy()方法完成拷貝操作要比采用循環(huán)的辦法完成數組拷貝操作效率高
12. 盡量避免在循環(huán)體中調用方法,因為方法調用是比較昂貴的。
13. 盡量避免在循環(huán)體中使用try-catch 塊,最好在循環(huán)體外使用try--catch塊以提高系統(tǒng)性能。
14. 在多重循環(huán)中,如果有可能,盡量將最長的循環(huán)放在最內層,最短的循環(huán)放在最外層,以減少循環(huán)層間的變換次數。
15. 在需要線程安全的情況下,使用List list = Collections.synchronizedList(new ArrayList());
16. 如果預知長度,就設置ArrayList的長度。
17. ArrayList 與 LinkedList 選擇,熟悉底層的實現(xiàn)原理,選擇適當的容器。
18. 字符串累加采用StringBuffer.
19. 系統(tǒng)I/O優(yōu)化,采用緩沖和壓縮技術。優(yōu)化性能。
20. 避免在類在構造器的初始化其他類
21 盡量避免在構造中對靜態(tài)變量做賦值操作
22. 不要在類的構造器中創(chuàng)建類的實例
23. 組合優(yōu)化繼承
24. 最好通過Class.forname() 動態(tài)的裝載類
25. JSP優(yōu)化,采用out 對象中的print方法代替println()方法
26 .采用ServletOutputStream 對象代替JSPWriter對象
27. 采用適當的值初始化out 對象緩沖區(qū)的大小
28. 盡量采用forward()方法重定向新的JSP
29. 利用線程池技術處理客戶請求
30.Servlet優(yōu)化
(1) 通過init()方法來緩存一些靜態(tài)數據以提高應用性能。
(2) 用print() 方法取代println()方法。
(3) 用ServletOutputStream 取代 PrintWriter.
(4) 盡量縮小同步代碼數量
31. 改善Servlet應用性能的方法
(1)不要使用SingleThreadModel
(2)使用線程池ThreadPool
32. EJB優(yōu)化
實體EJB:
(1)實體EJB中常用數據緩存與釋放
(2)采用延遲加載的方式裝載關聯(lián)數據
(3)盡可能地應用CMP類型實體EJB
(4)直接采用JDBC技術處理大型數據
33. 優(yōu)化JDBC連接
(1)設置合適的預取行值
(2)采用連接池技術
(3)全合理應用事務
(4)選擇合適的事務隔離層與及時關閉連接對象
34. PreparedStatemetn只編譯解析一次,而Statement每次都編譯解析。
35. 盡可能地做批處理更新
36. 通過采用合適的getXXX方法提高系統(tǒng)性能
37. 采用設計模式。
如何優(yōu)化JAVA代碼及提高執(zhí)行效率
張小喜告別996 實現(xiàn)高效編程 減少開發(fā)壓力 開啟Java高效編程之門(完整版高清視頻)百度網盤 ?
鏈接:
提取碼: aizj 復制這段內容后打開百度網盤手機App,操作更方便哦? ?
若資源有問題歡迎追問~ ?
北大青鳥設計培訓:如何寫出優(yōu)質Java代碼的4個技巧?
如果現(xiàn)在要求對你寫的Java代碼進行優(yōu)化,那你會怎么做呢?作者在本文介紹了可以提高系統(tǒng)性能以及代碼可讀性的四種方法,如果你對此感興趣,就讓java課程一起來看看吧。
我們平時的編程任務不外乎就是將相同的技術套件應用到不同的項目中去,對于大多數情況來說,這些技術都是可以滿足目標的。
然而,有的項目可能需要用到一些特別的技術,因此工程師們得深入研究,去尋找那些最簡單但最有效的方法。
在以前一篇文章中,我們討論了必要時可以使用的四種特殊技術,這些特殊技術可以創(chuàng)建更好的Java軟件;而本文我們將介紹一些有助于解決常見問題的通用設計策略和目標實現(xiàn)技術,即:?1.只做有目的性的優(yōu)化?2.常量盡量使用枚舉?3.重新定義類里面的equals()方法?4.盡量多使用多態(tài)性值得注意的是,本文中描述的技術并不是適用于所有情況。
另外這些技術應該什么時候使用以及在什么地方使用,都是需要使用者經過深思熟慮的。
1.只做有目的性的優(yōu)化大型軟件系統(tǒng)肯定非常關注性能問題。
雖然我們希望能夠寫出最高效的代碼,但很多時候,如果想對代碼進行優(yōu)化,我們卻無從下手。
最重要的是天下沒有免費的午餐,因此為了降低代價,我們通常會通過類似于緩存、循環(huán)展開或預計算值這類技術去實現(xiàn)優(yōu)化,這樣反而增加了系統(tǒng)的復雜性,也降低了代碼的可讀性。
如果這種優(yōu)化可以提高系統(tǒng)的性能,那么即使變得復雜,那也是值得的,但是做決定之前,必須首先知道這兩條信息:?1.性能要求是什么?2.性能瓶頸在哪里首先我們需要清楚地知道性能要求是什么。
如果最終是在要求以內,并且最終用戶也沒有提出什么異議,那么就沒有必要進行性能優(yōu)化。
但是,當添加了新功能或者系統(tǒng)的數據量達到一定規(guī)模以后就必須進行優(yōu)化了,否則可能會出現(xiàn)問題。
在這種情況下,不應該靠直覺,也不應該依靠檢查。
因為即使是像MartinFowler這樣有經驗的開發(fā)人員也容易做一些錯誤的優(yōu)化,正如在重構(第70頁)一文中解釋的那樣:如果分析了足夠多的程序以后,你會發(fā)現(xiàn)關于性能的有趣之處在于,大部分時間都浪費在了系統(tǒng)中的一小部分代碼中里面。
如果對所有代碼進行了同樣的優(yōu)化,那么最終結果就是浪費了90%的優(yōu)化,因為優(yōu)化過以后的代碼運行得頻率并不多。
因為沒有目標而做的優(yōu)化所耗費的時間,都是在浪費時間。
欄 目:Java編程
下一篇:沒有了
本文標題:java代碼重構優(yōu)化經驗 java代碼重構的思路
本文地址:http://mengdiqiu.com.cn/a1/Javabiancheng/17332.html
您可能感興趣的文章
- 04-09java貸款利率代碼 java利率是什么數據類型
- 04-09安卓輔助java代碼 安卓輔助用什么開發(fā)
- 04-09俄羅斯方法java源代碼 java編寫俄羅斯方塊代碼
- 04-07java入門小代碼 java簡單的代碼
- 04-07繪制圖像就java代碼 java繪制圖形代碼
- 04-07java代碼異步 java異步處理方法
- 04-07java修改運行中的代碼 java代碼在哪里修改
- 04-07java命令行代碼 java中命令行在哪打開
- 04-07java時鐘日歷代碼 java實現(xiàn)日歷
- 04-07java購物車系統(tǒng)源代碼 javabean購物車


閱讀排行
本欄相關
- 04-09java代碼重構優(yōu)化經驗 java代碼重構的
- 04-09java貸款利率代碼 java利率是什么數據
- 04-09安卓輔助java代碼 安卓輔助用什么開發(fā)
- 04-09俄羅斯方法java源代碼 java編寫俄羅斯
- 04-07java入門小代碼 java簡單的代碼
- 04-07繪制圖像就java代碼 java繪制圖形代碼
- 04-07java代碼異步 java異步處理方法
- 04-07java修改運行中的代碼 java代碼在哪里
- 04-07java命令行代碼 java中命令行在哪打開
- 04-07java時鐘日歷代碼 java實現(xiàn)日歷
隨機閱讀
- 01-10基于字符串移位包含的問題詳解
- 01-10c++隱式類型轉換示例分享
- 08-05織夢DedeCms如何獲取縮略圖的高度和寬
- 01-11帝國CMS統(tǒng)計留言數量的方法
- 08-05織夢首頁調用指定一篇文章body內容的
- 01-11WordPress評論禁止針對指定內容全英文
- 01-10C#中深度復制和淺度復制詳解
- 01-10C++實現(xiàn)旋轉數組的二分查找
- 08-05dede5.6和5.7版本中實現(xiàn)dede:list按權重排
- 01-10libevent庫的使用--定時器的使用實例