扣丁學堂教你java性能優化技巧

扣丁学堂教你java性能优化技巧

很多懂java或者參加過java培訓的同學都知道,Java的一些性能是可以優化的,本文呢綜合了各種Java性能優化的研究成果,涵蓋從JDK到Java集合使用、場景用例到和工具。希望對同學們有幫助.

1.如果在靜態構造器中有繁重的計算,也就是耗費CPU的邏輯代碼,請檢查其運行時間是否過度?如果是,將這些邏輯遷移到另外一個單獨的幫助類中。StaticconstructorcodeisnotJIT-optimizedinalotofcases

2.在進行byte作為String的構造參數時,需要將byte數組的一部分做個複製拷貝,否則,構造器會為整個原始緩衝做一個臨時拷貝;試圖避免不必要的內存分配,因為在內存使用超過1G+以上時會影響程序的性能,InefficientbytetoStringconstructor

3.變量對於大多數程序是非常有用的,因為它們縮短了代碼,但是當變量的所有成員已經確認是不變的常量,那麼使用預編譯的數組替代。Javavarargsperformanceissues:

4.儘可能使用StringBuilder替代StringBuffer。PrimitivetypestoStringconversionandStringconcatenation

5.使用閃存SSD替代傳統的硬盤HDD,這樣你可以將你的應用程序從I/O-bound轉變到CPU-bound,這對於設計到read/write流操作特別有用;現代操作系統都是在後臺寫數據,不會堵塞你的應用,你的寫操作只有在操作系統寫入磁盤的速度慢於你的應用產生數據的速度時,才會堵塞你的寫操作請求:I/Oboundalgorithms:SSDvsHDD

6.如果你的內存中有字符串或帶有String字段的對象的大量集合,在某些情況下,字少10%場景,這些字符串實際上可能會轉換為基本類型的值,你可以使用Object字段替代你的String字段,使用其提供的pack/unpack方法在字符串和對象之間來回轉換,這樣節省內存。如果你不將字符串轉換為基本類型,可以考慮將字符串轉為UTF-8的byte,可以隨時將byte轉回原始字符串。Stringpackingpart2:convertingStringstoanyotherobjects

7.如果有大量重複的字符串,使用String.intern減少內存損耗,提高性能:ReducingmemoryusagewithString.intern、String.interninJava6,7and8-part3、String.interninJava6,7and8-multithreadedaccess

8.嘗試使用Googleprotobuf或類似編碼技術編碼你整數數據,特別是這些數據值很小的情況下,這樣你會得到數據量大幅度減小後導致的低CPU損耗,能夠幫助你提高每個時間單元中存儲或讀取更多消息數量。

9.如果使用arraylist/set/map時,其key或值是基本類型,那麼使用Trove的maps/sets替代JDKmaps/sets,可以節省大量內存。Trovelibrary:usingprimitivecollectionsforperformance

10.當你的應用堆heap大小超過32G時,JVM會切換到64位的對象引用,意味著你的應用已經結束了佔用更少Heap空間的階段。GoingoverXmx32Gheapboundarymeansyouwillhavelessmemoryavailable

11.如果你使用內部類,缺省使用靜態的內部類;如果你使用一堆小的集合Collection,那麼試試使用java.util.Collections.empty*/singleton*方法實現小集合的內存高效率存儲;使用BitSet替代boolean的arrays/lists或一系列integer整數類型,bitset是內存和CPU緩存都很友好。AfewmorememorysavingtechniquesinJava

12.不要在多線程中共享一個java.util.Random實例,將其包裝在ThreadLocal中,Java7中使用java.util.concurrent.ThreadLocalRandom替代java.util.Random。

13.如果你希望有快速的Base64編碼器,使用Java8的java.util.Base64

14.不要使用exception,每個exception啟動需要1毫秒:CreatinganexceptioninJavaisveryslow

15.如果你使用:

if(!set.contains(key))

{

set.add(key);

//someextracodehere

}

直接使用add更快:

if(set.add(key)){

//sameextracodecouldbeaddedhere

}

同樣,contains+remove可以被remove直接替代。

16.如果要使用壓縮,考慮使用LZ4。Performanceofvariousgeneralcompressionalgorithms-someofthemareunbelievablyfast!

17.使用ByteBuffer替代ByteArrayOutputStream。java.io.ByteArrayOutputStream

18.如果你希望計算幾天這樣的短天數,那麼基於int/long進行手工實現會更快些。JSR310-Java8Date/Timelibraryperformance(aswellasJodaTime2.3andj.u.Calendar)

19.使用Matcher和Pattern替代String.matches,split,replaceAll,replaceFirst等方法。Regexp-relatedmethodsofString

20.如果你希望有一個快速的LinkedList代碼實現,考慮下面規則:

使用ArrayDeque實現基於隊列queue-based的算法

使用LinkedList的ListIterator

避免使用任何LinkedList方法接受或返回集合中元素的索引。

再次檢查是否有理由使用LinkedList

21.如果使用ArrayList,考慮下面規則:

將元素追加到集合尾部。

也從尾部移除元素

避免contains,indexOf和remove(Object)方法

避免更多的removeAll和retainAll方法

使用subList(int,int).clear來清除集合中的一部分。

22.Java8中使用G1垃圾回收機制時,使用減少字符串重複配置:-XX:+UseG1GC-XX:+UseStringDeduplication。

好啦,今天的分享就到這裡了,如果大家想學習更多的話,可以看看我們的視頻課哦

標籤: java 性能優化


分享到:


相關文章: