理論上 Java 不比其他語言更佔記憶體,但不良編碼習慣導致大量微小物件充斥堆疊。以下 9 條守則針對常見陋習給出具體優化方案。
new Boolean(),用 Boolean.valueOf()JDBC/ORM 大量封裝 boolean,若寫 new Boolean(true) 會產生海量物件。
正確: Boolean.TRUE / Boolean.FALSE 或 Boolean.valueOf(boolean) (內部返回單例)。
new Integer(),用 Integer.valueOf()JDK 快取 -128 ~ 127 共 256 個 Integer 實例。Integer.valueOf(int) 範圍內返回快取物件。
跨 JDK 相容: 自建 IntegerUtils.valueOf() 封裝快取邏輯。
StringBuffer/StringBuilderString s = a + b + c 產生大量中間 String 物件。實際專案見過單一方法拼 SQL 產生近 100 個 String 實例。
單執行緒用 StringBuilder,多執行緒用 StringBuffer。
無限制放入 HashMap 會撐爆記憶體。
方案: 採用 Ehcache、OSCache 等實現 LRU/FIFO/MRU 淘汰演算法的快取框架,設定最大容量。
深層繼承佔用方法區;深層呼叫消耗堆疊幀。扁平化設計、組合優於繼承。
縮小作用域,讓 GC 更早回收。避免方法開頭集中宣告所有變數。
static 變數,常量用 finalstatic 物件生命週期長、難回收。類內常量改用 private static final 或 final 實例常量。
資料庫連線、執行緒、大型工具物件 — 實作 ObjectPool 重用,避免頻繁建構/銷毀。
finally 區塊或 try-with-resources (Java 7+) 必須關閉所有資源,防洩漏。
| 陋習 | 優化方案 | 核心 API |
|---|---|---|
| new Boolean()/Integer() | valueOf() 單例/快取 | Boolean.valueOf, Integer.valueOf |
| 字串 + 拼接 | StringBuilder | StringBuilder.append() |
| HashMap 無限快取 | Ehcache/OSCache | CacheManager, Cache |
| 深層繼承/呼叫 | 扁平化、組合 | — |
| 提前宣告變數 | 就近宣告 | — |
| 濫用 static | final 常量 | final |
| 頻繁建構銷毀 | 物件池 | ObjectPool 模式 |
| 資源不關閉 | try-with-resources | AutoCloseable |
Java 高效能不靠「黑魔法」,靠的是消除陋習:單例替代新建、快取框架替代 HashMap、StringBuilder 替代拼接、物件池替代頻繁建構、資源確實關閉。九條守則貫徹執行,記憶體佔用與 GC 壓力將顯著下降。