Java 應用的延遲抖動可源自硬件、固件、OS、JVM(GC、JIT、類加載)乃至應用自身。高層難以彌補底層抖動,幸好實時 Java 在 JVM 與應用層提供了系統級工具。本文系統梳理抖動源頭與對策,並以一個簡單服務器演示調優全過程。
關鍵參數:-Xgcpolicy:metronome -Xgcthreads8 -Xmx700m -Xgc:targetUtilization=70
首次觸達類時觸發解析、驗證、初始化。熱點路徑外的異常類、反射生成類是常見「隱形炸彈」。
Class.forName(name); clazz.getName(); 強制初始化。-verbose:class 收集類列表,或使用 RATCAT / Real Time Application Execution Optimizer 自動化。JIT 異步編譯會搶佔應用線程;激進優化(如數組複製專門化)更可能導致「快慢路徑」極端分化。
Compiler.compileClass(clazz); Compiler.disable(); 消除運行時編譯抖動,犧牲峰值吞吐。標準 Java 線程模型僅提示優先級,映射到 OS 由實現定義,無法保證搶佔式調度。RTSJ 引入 RealtimeThread / NoHeapRealtimeThread:
Thread.yield()、自旋鎖等與 FIFO 衝突的模式。基於 ExecutorService 的簡單服務器 + 持續產生垃圾的 GCStressThread:
RealtimeThread(最高優先級 + FIFO):最差 19ms,吞吐回升至 357 ops/s,抖動顯著改善。代價是吞吐量下降約 40%,但換來了硬實時級的服務質量保證。
實時 Java 並非銀彈,而是「確定性換吞吐」的工具箱。根據業務 SLA 選擇:軟實時可在標準 JVM 做預加載/預編譯;硬實時需實時 JVM + RTSJ 線程 + 實時 GC。核心原則:在抖動源頭攔截,而非事後補救。