Java 性能調優常被視為「黑魔法」,部分源於平台複雜性,更源於社群長期依賴經驗直覺而非統計實證。本文拆解 9 個最荒謬的技術迷思。
最過時的迷思。90 年代確實慢,但經過 10+ 年 JIT 與 JVM 改進,現代 Java 性能極佳。6 項 Web 基準測試中,Java 框架 24 項指標有 22 項進入前四。JIT 基於剖析優化熱點路徑,編譯後代碼常匹敌 C++,且情況持續改善。歷史偏見導致此迷思存續,建議以最新基準數據為準。
MyObject obj = new MyObject(); 看似必定分配物件,實則 javac 與 JIT 可消除死代碼,甚至預測性優化。JRockit JIT 甚至可分解物件操作避免分配。上下文決定一切,過早優化產生反直覺結果。應構建代碼、用調優工具定位熱點再改進。
費曼語錄:「別騙自己,你最容易被騙。」編寫良好微基準極難,Java 平台複雜,常測到瞬間效應或 GC 噪音而非真實因素。只有有實際需求的團隊才應編寫,且必須公開原始碼、可復現、接受同儕審查。統計分析不可或缺,建議參考《Statistically Rigorous Java Performance Evaluation》或使用 Google Caliper 等成熟工具。
開發者傾向高估自己控制部分的重要性。現實中 演算法設計是根因的機率 < 10%。GC、資料庫存取、配置錯誤導致緩慢的可能性大得多。多數應用處理資料量較小,即使演算法非最優也不致嚴重。用實際生產數據揭示真因,測量而非猜測!
「計算機科學所有問題可透過中間層解決。」當架構理解受阻、分析停滯時,快取迷思抬頭。快取只會增加架構複雜度,下一位接手者更難理解。簡化重構常帶來更好性能且更易維護。評估快取必要性前,先收集命中率等統計證明其價值。
GC 需周期性停頓所有應用線程。實證研究:200ms 以上頻率變化人無法感知。200ms 或以下 STW 通常無影響(流媒體等極少數例外)。任何系統在線程數超過物理核心時都面臨 CPU 分時調度。開啟 GC 日誌測量實際停頓,再判斷是否真有問題。關鍵問自己:真的有用戶抱怨嗎?
源於「分配昂貴、修改便宜」的舊認知。現代硬體分配極高效(記憶體頻寬 2-3GB/s),正確實作物件池極難(多線程下更甚),帶來額外複雜性:全團隊必須理解、邊界須文檔化、持續維護審查。僅在 GC 停頓不可接受且調優重構無效時才考慮。
Oracle JDK 預設 Parallel Old(並行 STW 收集器)。CMS 允許應用線程與 GC 並行,但代價:雙 STW 階段、吞吐量通常降 50%、簿記開銷大。天下沒免費午餐。先確認 Parallel Old STW 真不可接受且無法調優,再考慮 CMS。指標必須來自等價生產系統。
分配率高導致短命物件提升老年代快速死亡,增大堆積只會延長 Full GC 停頓。修改堆大小前,必須理解物件分配與存活動態。老年代分佈情況特別重要。盲目調參數只會惡化局勢。
直覺常誤導,需實驗數據與工具可視化平台行為。GC 子系統是最佳例證。建議所有 Java 進程(含開發/生產環境)啟動參數:
-verbose:gc -Xloggc: -XX:+PrintGCDetails -XX:+PrintTenuringDistribution
使用 GCViewer、jClarity Censum 或自製腳本分析日誌,以數據驅動調優。