1 回答

TA貢獻1851條經驗 獲得超4個贊
帶有 FileInputStream 的 2MB 緩沖區(qū)可能不是最佳選擇。有關詳細信息,請參閱此問題。雖然它是在 Windows 上,但我在 Linux 上看到了類似的性能問題。根據操作系統(tǒng)的不同,分配一個臨時的大緩沖區(qū)可能會導致額外的mmap
調用和隨后的頁面錯誤。如此大的緩沖區(qū)也使 L1/L2 緩存變得無用。
從常規(guī)文件中讀取只會被短暫阻塞,并且不依賴于任何 Java 線程。
這并非總是如此。在您的基準測試中,文件顯然緩存在操作系統(tǒng)頁面緩存中,并且沒有發(fā)生設備 I/O。訪問真實硬件(尤其是旋轉磁盤)可能要慢幾個數(shù)量級。磁盤 I/O 的最壞時間是不完全可以預測的——它可以大到數(shù)百毫秒,這取決于硬件條件、I/O 隊列的長度、調度策略等。
JNI 臨界區(qū)的問題是每當發(fā)生延遲時,它可能會影響所有線程,而不僅僅是執(zhí)行 I/O 的線程。這對于單線程應用程序來說不是問題,但這可能會導致多線程應用程序中出現(xiàn)不需要的 stop-the-world 暫停。
反對 JNI 的另一個關鍵原因是與 GCLocker 相關的 JVM 錯誤。有時它們可能會導致冗余的 GC 周期或忽略某些 GC 標志。以下是一些示例(仍未修復):
JDK-8048556不必要的 GCLocker 啟動的年輕 GC
JDK-8057573如果 GCLocker 處于活動狀態(tài),則忽略 CMSScavengeBeforeRemark
JDK-8057586如果 GCLocker 處于活動狀態(tài),則忽略顯式 GC
所以,問題是你關心的是吞吐量還是延遲。如果您只需要更高的吞吐量,JNI critical 可能是正確的選擇。但是,如果您還關心可預測的延遲(不是平均延遲,而是 99.9%),那么 JNI critical 似乎不是一個好的選擇。
添加回答
舉報