提到 Java 開發的系統,許多開發者的第一反應是「佔內存」。雖然理論上 Java 應用並不比其他語言更耗記憶體,但大量實際案例確實顯示記憶體使用偏高。罪魁禍首並非語言本身,而是開發過程中形成的不良編碼習慣。本文整理 7 個立竿見影的優化技巧,助你從根源上減少不必要的物件創建與內存浪費。
Boolean 類型在 JDBC、ORM 框架中極為常見,但每次呼叫 new Boolean(true) 都會產生新物件。大量實例會嚴重擴大堆內存壓力。Boolean 類內建兩個靜態常量:
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
正確做法:直接使用 Boolean.TRUE、Boolean.FALSE,或呼叫 Boolean.valueOf(boolean)(內部直接返回上述常量)。
// 錯誤示範
ps.setBoolean("isClosed", new Boolean(true));
ps.setBoolean("isClosed", new Boolean(isClosed));
// 優化寫法
ps.setBoolean("isClosed", Boolean.TRUE);
ps.setBoolean("isClosed", Boolean.valueOf(isClosed));
Integer 在 JDK 內部緩存了 -128 ~ 127 之間的 256 個實例。呼叫 Integer.valueOf(int) 且參數落在此區間時,直接返回緩存物件,避免重複分配。若專案需跨 JDK(如 IBM JDK),可自行封裝工具類統一入口。
經典議題不再贅述,但實戰中仍常見以 + 拼接 SQL 導致單一方法產生上百個 String 臨時物件。採用 StringBuilder(單執行緒)或 StringBuffer(多執行緒)可大幅降低臨時物件數量與 GC 壓力。
以 HashMap 緩存基礎資料雖能提速,但若無淘汰機制,記憶體將隨資料增長而無限膨脹。建議引入成熟快取框架(Ehcache、Caffeine、Redis),配置 LRU、FIFO、TTL 等策略,限制快取容量上限,兼顧效能與記憶體安全。
過深的繼承鏈會增加類載入與方法表開銷;過深的呼叫棧則佔用大量棧幀空間。採用組合優於繼承、扁平化業務邏輯、避免不必要的委派鏈。
變數僅在真正需要時才宣告並實例化,縮短物件生命週期,讓 GC 更早回收記憶體,同時提升程式碼可讀性。
static 變數生命週期隨類載入器,易造成記憶體洩漏。類內部常量優先用 private static final 或 final,避免長期佔用堆空間。
Java 記憶體優化的核心在於減少無謂物件創建與控制物件生命週期。養成上述 7 個習慣,配合 JVM 參數調優(如 -Xms/-Xmx、GC 策略選擇),即可讓 Java 系統輕量、穩定運行。