在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java  網(wǎng)絡(luò)安全/ NIO 文件讀寫效率問題

NIO 文件讀寫效率問題

我使用NIO完成一個大文件復(fù)制函數(shù),但發(fā)現(xiàn)該函數(shù)的執(zhí)行很不穩(wěn)定。對此有以下困惑:

  1. 效率差異嚴(yán)重:每次復(fù)制文件耗時差異很大,且無規(guī)律,對一個2G的文件賦值,最快3秒,最慢達到20s;
  2. 內(nèi)存泄露:JVM占用的內(nèi)存并沒有異常,但OS使用的內(nèi)存迅速飆升,我猜測應(yīng)該是“直接內(nèi)存”的使用,但不清楚如何釋放這部分內(nèi)存;
  3. 系統(tǒng)負載:我觀察到代碼執(zhí)行后,系統(tǒng) CPU,內(nèi)存,磁盤都迅速飆高,但代碼停止后CPU,磁盤負載不能及時恢復(fù);

環(huán)境信息:Windows10,JDK 8,具體代碼如下:

public class CopyTest {

    private static final String PATH = "";  // TODO

    public static void main(String[] args) throws IOException {
        for (int i = 0; i < 10; i++) {
            fileChannelCopy();
        }
        System.in.read();
    }

    private static void fileChannelCopy() throws IOException {
        long start = System.currentTimeMillis();
        FileChannel read = new FileInputStream(PATH).getChannel();
        FileChannel writer = new RandomAccessFile(PATH + "-"
                + new Random(System.currentTimeMillis()).nextInt(), "rw").getChannel();
        long readSize = 0;
        long size = read.size() / 30;
        ByteBuffer toRead, toWrite = null;
        while (readSize < read.size() // 未讀完
                && (read.size() - readSize) > size) {  // 剩余未讀大于size
            toRead = read.map(FileChannel.MapMode.READ_ONLY, readSize, size);
            toWrite = writer.map(FileChannel.MapMode.READ_WRITE, readSize, size);
            toWrite.put(toRead);
            readSize += size;
            toRead.clear();
            toWrite.clear();
        }
        toRead = read.map(FileChannel.MapMode.READ_ONLY, readSize, read.size() - readSize);
        assert toWrite != null;
        toWrite.put(toRead);
        toRead.clear();
        toWrite.clear();
        read.close();
        writer.close();
        long end = System.currentTimeMillis();
        System.out.println("FileChannel copy file using " + (end - start) / 1000 + "s");
    }

某次執(zhí)行Jprofiler觀測到的運行狀態(tài)
clipboard.png

我發(fā)現(xiàn)復(fù)制的速度與CPU Load密切相關(guān)

回答
編輯回答
九年囚

NIO用在網(wǎng)絡(luò)上效果很好,但用在文件存取上似乎作用并不明顯(除非下載文件這種場景,例如Tomcat的sendfile特性)。

用NIO和傳統(tǒng)方法(FileInput/OutputStream)比較下就知道了。

2018年8月6日 19:43
編輯回答
愛是癌

就我所了解的,磁盤是順序讀寫設(shè)備,無論你有多少線程在讀寫,磁盤的數(shù)據(jù)讀寫是不能并發(fā)的。

2017年3月31日 09:51
編輯回答
陌如玉

操作系統(tǒng)文件緩存;java堆外內(nèi)存;系統(tǒng)調(diào)用

2017年9月1日 05:37