// 單位元組讀寫、無緩衝、逐行 println
FileReader fr = new FileReader("big.txt");
int c;
while ((c = fr.read()) != -1) System.out.print((char)c); // 極慢
String sql = "SELECT * FROM t WHERE ";
for (String cond : conditions) {
sql += cond + " AND "; // 每次迴圈建立新 String、產生垃圾
}
spring.datasource.hikari:
maximum-pool-size: 20 # CPU 核心數 * 2 + 1
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
leak-detection-threshold: 5000
# 固定堆避免震盪
-Xms4g -Xmx4g
# G1 目標停頓 100ms 內
-XX:+UseG1GC
-XX:MaxGCPauseMillis=100
-XX:G1HeapRegionSize=16m
# 物件年齡閾值 (提早晉升長壽物件)
-XX:MaxTenuringThreshold=10
# 大物件直接進老年代
-XX:PretenureSizeThreshold=1m
JIT 啟用 `-XX:+DoEscapeAnalysis` (預設開啟) 後,未逃逸物件可標量替換 (拆解為局部變數)、棧上分配、同步消除,零分配壓力。
// 熱點方法中,User 未逃逸 → JIT 可能優化為棧上分配
public void process() {
User u = new User("Alice"); // 無 this 引用外洩
u.setAge(20);
log.info(u.getName());
}
| 誤區 | 事實 |
|---|---|
| `+` 拼接字串極慢 | JIT 會優化為 `StringBuilder`,單行表達式無害 |
| 物件池通用提升效能 | 現代 GC 極快,除非物件建構極貴重 (DB連線、執行緒),否則池化反而增加 GC 掃描負擔 |
| 手動 `System.gc()` 釋放記憶體 | 觸發 Full GC,嚴重卡頓,破壞分代假說 |
| 用 `Vector`/`Hashtable` 線程安全 | 鎖粒度粗、效能差,改用 `Collections.synchronizedList` 或並發集合 (`ConcurrentHashMap`) |
| 所有方法加 `final` 提升內聯 | JIT 基於型別檢測自動內聯,`final` 影響微乎其微 |
效能優化是系統工程,而非拼湊技巧。建立「監測→分析→優化→驗證」閉環,配合現代 JVM (G1/ZGC)、高效庫 (HikariCP, Netty, Jackson)、合理架構 (緩存、非同步、分庫分表),才能持續榨乾硬體效能。