Java性能优化方面的程序优化知识点归纳,希望对你有所帮助
常用的程序設計優化技巧:
1、字符串優化處理
(1)String 類的特點:不變性、針對常量池的優化( String.intern() 方法的意義)
(2)subString 方法的內存泄漏 :
(3)字符串分割和查找不要使用 split 函數,效率低,而是使用 StringTokenizer 或者 indexOf結合 subString() 函數完成分割。
(4)用 charAt ()方法代替 startWith ()方法。
(5)對于靜態字符串或者變量字符串的連接操作, Java 在編譯的時候會進行徹底的優化,將多個連接操作的字符串在編譯時合成一個單獨的字符串,而不是生成大量的 String 實例。只生成一個對象。
(6)在無需考慮線程安全情況下盡量使用 StringBuilder 。
(7)StringBuffer 和 StringBuilder 初始化的時候都可以設置一個初始值,默認是 16B 。如果字符串的長度大于 16B 的時候,則需要進行擴容。擴容策略是將原有的容量大小翻倍,以新的容量申請內存空間,建立 char 數組,然后將數組中的內容復制到這個新的數組中,使用 Arrays.copyOf() 函數。因此,如果能預先評估 StringBuilder 的大小,則可以節省這些復制操作,從而提高系統的性能。
2、List 接口
( 1 ) ArrayList 和 Vector 的區別:它們幾乎使用了相同的算法,它們的唯一區別是對多線程的支持。 ArrayList 是不安全的,而 Vector 是線程安全的。
( 2 ) LinkedList 和 ArrayList 的區別:
|---1 、 linkedList 采用鏈表實現,適合于數據刪除和插入非常頻繁的情況,不適合隨機訪問。
|---2 、 ArrayList 采用數組實現,適用于隨機查找和順序讀的情況,不適合刪除和插 入數據非常頻繁的場景。
(3)基于數組的 List 都會有一個容量參數。當 ArrayList 所存儲的元素容量超過其已有大小的時候就會進行擴容,數組的擴容會導致整個數組進行一次內存復制。因此合理的數組大小會減小數組擴容的次數從而提高系統性能。
(4)遍歷列表的時候盡量使用迭代器,速度快。
2、Map 接口:
(1)HashMap 的實現原理:簡單的說, HashMap 就是將 key 做 hash 算法,然后將 hash 值映射到內存地址,直接取得 key 所對應的數據。在 HashMap 中,底層數據結構使用的是數組,所謂的內存地址指的是數組的下標索引。
(2)容量參數與擴容:默認情況下, hashmap 的初始容量為 16 ,負載因子為 0.75 ,也就是說當 hashmap 的實際容量達到了初始容量 * 負載因子( hashmap 內部維護的一個 threshold 值)的時候, hashmap 就會進行擴容。在擴容時,會遍歷整個 hashmap ,因此應該設置合理的初始大小和負載因子,可以減小 hashmap 擴容的次數。
(3)LinkedHashMap-- 有序的 HashMap : HashMap 的最大缺點是其無序性,被存入到 Hashmap 中的元素,在遍歷 HashMap 的時候,其輸出不一定按照輸入的順序,而是 HashMap 會根據 hash 算法設定一個查找高效的順序。如果希望保存輸入順序,則需要使用 LinkedHashMap 。LinkedHashmap 在內部又增加了一個鏈表,用于保存元素的順序。
(4)LinkedList 可以提供兩種類型的順序:一個是元素插入時候的順序,一個是最近訪問的順序。注意: LinkedHashMap 在迭代過程中,如果設置為按照最后訪問時間進行排序,即:每當使用 get() 方法訪問某個元素時,該元素便會移動到鏈表的尾端。但是這個時候會出現異常,因此, LinkedHashMap 工作在這種模式的時候,不能在迭代器中使用 get() 操作。
(5)關于 ConcurrentModificationException :該異常一般會在集合迭代過程中被修改時拋出。因此,不要在迭代器模式中修改集合的結構。這個特性適合于所有的集合類,包括 HashMap 、 Vector 、 ArrayList 等。
(6)TreeMap-- 如果要對元素進行排序,則使用 TreeMap 對 key 實現自定義排序,有兩種方式:在 TreeMap 的構造函數中注入一個 Comparator 或者使用一個實現了 Comparable 的 key 。
(7)如果需要將排序功能加入 HashMap ,最好是使用 Treemap 而不是在應用程序自定義排序。
(8)HashMap 基于 Hash 表實現, TreeMap 基于紅黑樹實現。
3 、 Map 和 Set 的關系:
( 1 )所有 Set 的實現都只是對應的 Map 的一種封裝,其內部維護一個 Map 對象。即: Set只是相應的 Map 的 Value 是一種特殊的表現形式的一種特例。
( 2 ) Set 主要有三種實現類: HashSet 、 LinkedHashSet 、 TreeSet 。其中 HashSet 是基于 Hash 的快速元素插入,元素之間無序。 LinkedHashSet 同時維護著元素插入順序,遍歷集合的時候,總是按照先進先出的順序排序。 TreeSet 是基于紅黑樹的實現,有著高效的基于元素 Key 的排序算法。
4 、優化集合訪問代碼:
( 1 )、分離循環中被重復調用的代碼:例如, for 循環中使用集合的 size() 函數,則不應該把這個函數的調用放到循環中,而是放到循環外邊、
( 2 )、省略相同的操作:
5 、 RandomAccess 接口:通過 RandomAccess 可知道 List 是否支持隨機快速訪問。同時,如果應用程序需要通過索引下標對 List 做隨機訪問,盡量 buyaoshiyongLinkedList , ArrayList 或者 Vector 可以。
6 、 JavaNIO 的特性:
1 、為所有的原始類型提供 Buffer 支持。
2 、使用 Java.nio.charset.Charset 作為字符編碼解碼解決方案。
3 、增加通道抽象代替原有的 IO 流抽象。
4 、支持鎖和內存映射文件的文件訪問接口。
5 、提供基于 Selector 的異步網絡 IO 。
7 、 Java 中 NIO 的使用。 Channel 是一個雙向通道,即可讀也可寫。應用程序不能直接操作 Channel ,必須借助于 Buffer 。例如讀數據的時候,必須把數據從通道讀入到緩沖區,然后在緩沖區中進行讀取。以文件讀取為例,首先通過文件輸入流獲得文件通道,然后把文件通道的內容讀入到緩沖區中,然后就可以對緩沖區操作。
8 、 Buffer 的基本原理:
1 、 Buffer 的創建: Buffer 的靜態 allocate(int size) 方法或者 Buffer.wrap(byte[]src) 。
2 、 Buffer 的工作原理:三個變量: position ,代表當前緩沖區的位置,寫緩沖區的時候,將從 position 的下一個位置寫數據。 Capacity ,代表緩沖區的總容量上限。 Limit ,緩沖區的實際上限,也就是說,讀數據的時候,數據即是從 position 到 limit 之間的數據
3 、 flip 操作: limit=position,position=0, 一般是在讀寫切換的時候使用。寫完數據之后,需要限定下有效數據范圍,才能讀數據;
4 、 clear 操作: position-0 , limit=capacity. 。為重新寫入緩沖區做準備。
5 、 rewind 操作: position=0 ,為讀取緩沖區中有效數據做準備,一半 limit 已經被合理設置。
9 、讀寫緩沖區:
1 、 public byte get() :順序讀取緩沖區的一個字節, position 會加一
2 、 public Buffer get(byte[]dst): 將緩沖區中的數據讀入到數組 dst 中,并適當的移動 position
3 、 public byte get(int index) :得到第 index 個字節,但不移動 posoiion
4 、 public ByteBuffer put(byte b) :將字節 b 放入到緩沖區中,并移動 position
5 、 public ByteBuffer put(int index,byte b) :將字節 b 放到緩沖區的 index 位位置
6 、 pubglic final ByteBuffer(byte[]src) :將字節數組 src 放到緩沖區中。
10 、標志緩沖區:類似于一個書簽的功能,在數據的處理過程中,可隨時記錄當前位置。然后在任意時刻,回到這個位置。 Mark 用于記錄當前位置, reset 用于恢復到 mark 所在的位置、
11 、復制緩沖區:使用 Buffer 的 duplicate 方法可以復制一個緩沖區,副本緩沖區和原緩沖區共享一份空間但是有有著獨立的 position 、 capacity 和 limit 值。
20 、緩沖區分片:緩沖區分片使用 slice 方法實現。它將在現有的緩沖區中,創建的子緩沖區。子緩沖區和父緩沖區共享數據。這個方法有助于將系統模塊化。緩沖區切片可以將一個大緩沖區進行分割處理,得到的子緩沖區都具有緩沖的緩沖區模型結構;因此。這個操作有助于系統的模塊化。
12 、只讀緩沖區:只讀緩沖區可以保證核心數據的安全,如果不希望數據被隨意篡改,返回一個只讀緩沖區是很有幫助的。
13 、文件映射到內存: NIO 提供了一種將文件映射到內存的方法進行 IO 操作,這種方法比基于流 IO 快很多。這個操作主要由 FileChanne.map() 操作。使用文件內存的方式,將文本通過 FileChannel 映射到內存中。然后從內存中讀取數據。同時,通過修改 Buffer, 將對內存中數據的修改寫到對應的硬盤文件中。
14 、處理結構化數據:散射和聚集。散射就是將數據讀入到一組 bytebuffer 中,而聚集正好相反。通過 ScatteringByteChannel 和 GatheringByteChannel 可以簡化對結構數據的操作。
15 、直接內存訪問: DirectBuffer 直接分配在物理內存中,并不占用對空間,因此也不受對空間限制。 DirectBuffer 的讀寫操作比普通 Buffer 塊,因為 DirectBuffer 直接操縱的就是內核緩沖區。
16 、引用類型:強、軟、若、虛四種引用類型。
WeakHashMap :是弱引用的一中典型應用,它使用弱引用作為內部數據的存儲方案。可以作為簡單的緩存表解決方案。
如果在系統中,需要一張很大的 Map 表, Map 中的表項作為緩存之用。這也意味著即使沒能從該 Map 中取得相應地數據,系統也可以通過選項方案獲取這些數據,雖然這樣會消耗更多的時間,但是不影響系統的正常運行。這個時候,使用 WeakHashMap 是最合適的。因為 WeakHashMap 會在系統內存范圍內,保存所有表項,而一旦內存不夠,在 GC 時,沒有被引用的又會很快被清除掉,避免系統內存溢出。
17 、有助于改善系統性能的技巧:
1 、慎用異常: for 循環中使用 try-catch 會大大降低系統性能
2 、使用局部變量:局部變量的訪問速度遠遠高于類的靜態變量的訪問速度,因為類的 變量是存在在堆空間中的。
3 、位運算代替乘除法:右移代表除以二、左移代表乘以二。
4 、有的時候考慮是否可以使用數組代替位運算。
5 、一維數組代替二維數組。
6 、提取表達式:盡可能讓程序少做重復的計算,尤其要關注在循環體的代碼,從循環提中提取重復的代碼可以有效的提升系統性能。
為了讓學習變得輕松、高效,今天給大家免費分享一套Java入門教學資源。幫助大家在成為Java架構師的道路上披荊斬棘。需要入門的資料歡迎加入學習交流群:9285,05736
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Java性能优化方面的程序优化知识点归纳,希望对你有所帮助的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux相关英文书记,Linux常用软
- 下一篇: php常用函数、算法,PHP常用函数和常