首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 代碼性能優化 28 條實戰準則與最佳實踐

     編輯:Java 相關知識

前言

代碼層面的優化雖無法替代架構設計與演算法優化,但在高併發、大數據、低延遲場景下,累積的微小優化往往能帶來顯著吞吐提升。本文整理 28 條經驗準則,按優化維度分類,附原理分析與代碼對比。

一、對象創建與生命週期

  1. 盡量使用 final 修飾類/方法:允許 JIT 編譯器內聯優化,消除虛方法調用開銷。String、包裝類均為 final。
  2. 重用對象,特別是 String:字符串拼接用 StringBuilder(單線程)或 StringBuffer(線程安全),避免產生大量中間 String 對象觸發頻繁 GC。
  3. 優先使用局部變量:棧分配、隨棧幀銷毀、無 GC 壓力;實例/靜態變量在堆上,需 GC 回收。
  4. 及時關閉流/連接:try-with-resources (Java 7+) 確保資源釋放,避免句柄洩漏導致系統資源耗盡。
  5. 減少重複計算:循環邊界條件提取為局部變量。
    for (int i=0, len=list.size(); i<len; i++) 避免每次調用 size()。
  6. 採用懶加載:按需創建昂貴對象(如數據庫連接、大型緩存),降低啟動延遲與記憶體峰值。
  7. 慎用異常控制流程:異常創建堆疊追蹤開銷極大,僅用於真正錯誤場景,不用於業務邏輯分支。
  8. 避免循環內 try-catch:將 try-catch 移至循環外層,減少棧幀操作開銷。
  9. 預估集合初始容量:new ArrayList(5000)、new HashMap(1024) 避免擴容拷貝。HashMap 容量建議 2 的 N 次冪,負載因子 0.75 時閾值為 capacity*0.75。
  10. 大量數據複製用 System.arraycopy():原生方法,JIT 內聯優化,比手寫循環快數倍。
  11. 乘除法用位移操作:x * 8 → x << 3,x / 16 → x >> 4(JIT 通常會自動優化,手寫可提高可讀性)。
  12. 循環內避免創建對象引用:Object obj = null; for(...) { obj = new Object(); } 僅佔用一個引用槽位。

二、集合選擇與使用

  1. 確定大小用數組,不定用 ArrayList:數組內存緊湊、無擴容、隨機訪問最快。
  2. 非線程安全首選 ArrayList/HashMap/StringBuilder:Vector/Hashtable/StringBuffer 同步開銷大,已被淘汰。
  3. 不要將數組聲明為 public static final:引用不可變,但數組內容可變,存在安全隱患;改用 Collections.unmodifiableList 或防御性複製。
  4. 恰當使用單例:控制資源訪問(連接池)、控制實例創建、跨線程共享數據。雙重檢查鎖(DCL)需 volatile 修飾實例變量。
  5. 減少靜態變量使用:靜態變量生命週期 = 類生命週期,持有大對象導致內存洩漏(類卸載困難)。
  6. 及時銷毀無用 Session:HttpSession.invalidate() 釋放內存,避免序列化/持久化開銷。
  7. 實現 RandomAccess 的列表用 for 循環遍歷:ArrayList 實現 RandomAccess,for(i=0; i<size; i++) 比 for-each(迭代器)快;LinkedList 則相反。
  8. 同步塊代替同步方法:縮小鎖粒度,僅同步必要代碼段,提高併發度。

三、常量與基礎類型

  1. 常量用 static final 大寫命名:編譯期進入常量池,運行期直接取值;命名規範便於識別。
  2. 刪除無用代碼/導入:IDE 警告 The value of the local variable is not used 應清理,減少類文件體積與類加載時間。
  3. 運行期避免反射:反射涉及安全檢查、方法查找、訪問權限修改,性能差 10-100 倍。啟動階段反射緩存 Method/Constructor 對象供運行期複用。
  4. 使用連接池與線程池:HikariCP、ThreadPoolExecutor 重用昂貴資源,避免頻繁創建銷毀開銷。
  5. IO 操作使用緩衝流:BufferedInputStream/Reader、BufferedOutputStream/Writer 減少系統調用次數,提升吞吐數量級。
  6. 隨機訪問多用 ArrayList,增刪多用 LinkedList:ArrayList 底層數組 O(1) 訪問,O(n) 增刪;LinkedList 雙向鏈表 O(1) 增刪,O(n) 訪問。
  7. public 方法參數不超過 3-4 個:過多參數違背面向對象封裝,封裝為 DTO/VO 對象傳遞。
  8. 字符串比較把常量放前面:"const".equals(str) 避免 NullPointerException。
  9. 避免基本類型窄化強制轉換溢出:long → int 可能截斷高位,轉換前校驗範圍。
  10. 基本類型轉 String:toString() > String.valueOf() > +"":Integer.toString() 直接調用;String.valueOf() 內部調用 toString() 並做空檢查;+"" 隱式創建 StringBuilder 追加再 toString(),最慢。

驗證數據:基本類型轉 String 性能對比 (50,000 次)

String.valueOf():11ms
Integer.toString():5ms
i + "":25ms

總結

性能優化是權衡的藝術:可讀性 > 正確性 > 性能。上述準則在熱點路徑(高頻調用、大數據處理、核心邏輯)應用收益最大。建議配合 JMH (Java Microbenchmark Harness) 進行微基準測試驗證優化效果,避免「過早優化」陷阱。JVM JIT 編譯器已能自動完成大量優化(內聯、逃逸分析、標量替換),開發者應專注於算法複雜度、數據結構選擇、資源管理等高層決策。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved