在為 OneAPM 客戶提供技術支援的過程中,我們經常發現許多開發者未察覺代碼中存在大量異常拋出。消除這些不必要的異常後,應用程式執行速度往往顯著提升。這引發了我們的疑問:Java 異常處理究竟會帶來多大的效能開銷?既然異常是錯誤處理的核心機制,無法完全摒棄,我們便設計了一項實驗來量化其影響。
實驗基於一段會隨機拋出異常的簡單代碼。雖然這不算嚴謹的基準測試,且 HotSpot 編譯器在運行時可能對代碼進行優化,但結果仍具參考價值。實驗顯示,單純拋出與捕獲異常的成本極低,約為每次 0.02 毫秒。除非在極短時間內拋出數十萬次異常,否則這點開銷幾乎可忽略不計。

然而,這並未解釋為何實際生產環境中異常會導致嚴重效能下降。顯然,我們忽略了關鍵環節。
重新審視後發現,真正的效能損耗源於「為處理異常而執行的補償代碼」。例如重試資料庫連線、執行回滾操作、記錄詳細日誌等。這些業務邏輯往往涉及 I/O、網路呼叫或複雜計算,才是效能瓶頸的真兇。
更關鍵的是堆疊追蹤的收集。修改實驗代碼加入堆疊追蹤獲取後,效能影響較單純拋捕異常放大 10 倍。實際應用中,異常常跨多層被捕獲、包裝、重拋(如 JDBC 驅動層 → 框架層 → 業務層),每一層若都記錄堆疊追蹤,開銷成倍增加。加上將冗長堆疊追寫入日誌檔或控制台的 I/O 成本,效能影響不容小覷。
Java 語言設計本意是鼓勵正確使用異常:濫用異常會讓程式跑得更慢,倒逼開發者養成良好習慣。