在 JVM 故障排查與效能調優中,GC 日誌是核心觀測數據來源。傳統參數 -XX:+PrintGCTimeStamps 輸出的是 **JVM 啟動以來的相對秒數** (如 12.345:),這在以下場景極不便利:
自 JDK 8u40 / JDK 9 起,強烈建議改用 -XX:+PrintGCDateStamps (或統一參數 -Xlog:gc*:file=gc.log:time,uptime,level,tags),輸出 **ISO 8601 絕對時間戳** (如 2024-01-15T14:30:45.123+0800),大幅提升可讀性與關聯分析效率。
| 參數 | 輸出格式範例 | 優點 | 缺點 | 適用版本 |
|---|---|---|---|---|
-XX:+PrintGCTimeStamps | 12.345: [GC ... | 早期版本通用 | 相對時間、無時區、重啟歸零、難以關聯 | JDK 6+ |
-XX:+PrintGCDateStamps | 2024-01-15T14:30:45.123+0800: [GC ... | 絕對時間、含時區、人類可讀、易關聯 | 需 JDK 8u40+ / JDK 9+ | JDK 8u40+ |
-Xlog:gc*:file=gc.log:time,uptime,level,tags | [2024-01-15T14:30:45.123+0800][info][gc] ... | 統一日誌框架、結構化、可選欄位 | 語法較複雜、需 JDK 9+ | JDK 9+ (推薦) |
# 統一日誌框架 (JDK 9+ 推薦)
-Xlog:gc*:file=/var/log/app/gc-%t.log:time,uptime,level,tags:filecount=10,filesize=100m
# 等效傳統參數組合 (JDK 8 相容)
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintTenuringDistribution
-XX:+PrintHeapAtGC
-Xloggc:/var/log/app/gc-%t.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100M
場景: 電商下單介面間歇性超時 (10s+),業務日誌顯示 2024-01-15 14:30:45.200 ERROR OrderService - 下單超時。
1245.321: [Full GC ... 8.921 secs]
1246.102: [GC pause ... 0.045 secs]
分析痛點: 需知 JVM 啟動時間 (如 14:10:00),心算 1245 秒 ≈ 20 分鐘,對應 14:30:45。若 JVM 重啟過、日誌輪轉過、多實例部署,對極其困難。
2024-01-15T14:30:45.123+0800: [Full GC ... 8.921 secs]
2024-01-15T14:30:54.044+0800: [GC pause ... 0.045 secs]
分析優勢: 直接肉眼對齊業務日誌 14:30:45.200,確認 Full GC 耗時 8.9s 導致請求線程阻塞,定位耗時 30 秒 vs 30 分鐘。
若現有日誌分析工具 (如 GCViewer、GCEasy) 僅支援相對時間,可同時啟用:
-XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps
# 輸出:2024-01-15T14:30:45.123+0800: 1245.321: [GC ...
新版 -Xlog 亦支援雙欄位:
-Xlog:gc*:file=gc.log:time,uptime,level
TZ 環境變數設定正確 (如 TZ=Asia/Taipei),否則 GC 日誌時區與業務日誌不一致-Xlog:gc*:stdout:time,uptime,level),由側車收集器統一處理PrintGCDateStamps 以極低遷移成本 (僅增一參數) 換取 GC 日誌時間維度的質變升級。在微服務、容器化、多時區協作的現代架構中,絕對時間戳是可觀測性的基礎設施。建議:**所有 JDK 8u40+ 專案立即遷移,JDK 9+ 專案直接採用統一 `-Xlog` 框架。**