我有一個程序可以創建一個大小約爲50MB的文件。在此過程中,程序會頻繁地重寫文件的各個部分,並將更改強制到磁盤上(大約100次)。它使用FileChannel並通過fc.read(...),fc.write(...)和fc.force(...)指導ByteBuffers。多個JVM的I/O性能(受Windows 7影響,Linux有效)
新文本:
我對現在的問題一個更好的視野。 問題似乎是,我使用三個不同的JVM來修改一個文件(一個創建它,另外兩個(從第一個啓動)寫入它)。在下一個JVM啓動之前,每個JVM都會正確關閉該文件。 問題是,該文件的fc.write()成本偶爾會通過第三個JVM的頂端(按正常成本的100倍的順序)。也就是說,所有的寫操作都是同樣緩慢的,它不僅僅是一個很長的寫操作。有趣的是,有一種方法可以在啓動JVM之間插入延遲(2秒)。毫不拖延,寫作總是緩慢,延遲,寫作每隔一段時間左右緩慢。
我也發現這個Stackoverflow: How to unmap a file from memory mapped using FileChannel in java?它描述了映射文件的問題,我沒有使用。
我懷疑可能會發生什麼: 當我調用close()時,Java不會完全釋放文件句柄。當下一個JVM啓動時,Java(或Windows)會識別對該文件的併發訪問,併爲該文件安裝一些昂貴的併發處理程序,從而導致寫入代價高昂。 會有道理嗎?
該問題發生在Windows 7(Java 6和7,在兩臺機器上測試過)上,但不在Linux下(SuSE 11.3 64)。
舊文:
問題: 從從日食一個JUnit測試工具或從控制檯啓動程序正常工作,它需要3秒左右。 通過一個ant任務(或通過使用ProcessBuilder踢出單獨的JVM通過JUnit)啓動程序,可以將程序減慢到70-80秒,以完成同一任務(因子20-30)。
使用-Xprof揭示 'force0' 和 'PWRITE' 的使用穿過屋頂從34.1%(76個+ 20抽動)至97.3%(3587 + 2913 + 751抽動): 快速運行:
27.0% 0 + 76 sun.nio.ch.FileChannelImpl.force0
7.1% 0 + 20 sun.nio.ch.FileDispatcher.pwrite0
[..]
運行緩慢:
Interpreted + native Method
48.1% 0 + 3587 sun.nio.ch.FileDispatcher.pwrite0
39.1% 0 + 2913 sun.nio.ch.FileChannelImpl.force0
[..]
Stub + native Method
10.1% 0 + 751 sun.nio.ch.FileDispatcher.pwrite0
[..]
GC和編譯可以忽略不計。
更多的事實:
沒有其他的方法顯示在-Xprof輸出顯著變化。
- 它要麼很快,要麼非常緩慢,從來不介於兩者之間。
- 內存是沒有問題的,所有的測試機器至少有8GB,該過程使用< 200MB
- 重新啓動計算機並不能幫助病毒掃描程序和類似的東西
- 開關沒有影響
- 當過程是緩慢的,幾乎沒有任何CPU使用率
- 這是從未緩慢從一個正常的JVM運行時,它
- 這是很在從第一JVM啓動一個JVM上運行它時,(通過的ProcessBuilder持續放緩或作爲螞蟻任務)
- 所有JVM都完全相同。我通過RuntimeMXBean輸出System.getProperty(「java.home」)和JVM選項RuntimemxBean = ManagementFactory.getRuntimeMXBean(); List arguments = RuntimemxBean.getInputArguments();
- 我在兩臺使用Windows7 64位,Java 7u2,Java 6u26和JRockit的機器上進行了測試,但機器的硬件不同,但結果非常相似。
- 我也從外部Eclipse(命令行螞蟻)測試它,但沒有差異。
- 整個程序是由我自己編寫的,它所做的只是讀取和寫入該文件,不使用其他庫,尤其是沒有本地庫。 -
而且一些可怕的事實,我只是不願相信任何意義:
- 刪除所有的類文件,有時重建項目(很少)幫助。該程序(嵌套版本)運行速度快一次或兩次,然後又變得非常慢。
- 安裝一個新的JVM總是有幫助的(每一次!),這樣(嵌套的)程序至少運行一次!由於JDK-jre和JRE-jre至少可以正常工作一次,因此安裝JDK的計數爲兩個。重新安裝JVM不會有幫助。重新啓動也沒有。我還沒有試過刪除/重新啓動/重新安裝...
- 這些是我唯一能夠爲嵌套程序獲得快速程序運行時的兩種方法。
問題:
- 什麼可能會導致嵌套的JVM這種性能下降?
- 這些方法究竟做什麼(pwrite0/force0)? -