2010-11-04 127 views
8

我使用MappedByteBuffer來加速文件的讀/寫操作()。我的問題如下:我們是否需要使用MappedByteBuffer.force()將數據刷新到磁盤?

  1. 我不知道我是否需要使用.force()方法來刷新內容磁盤。看起來像沒有.force(),.getInt()仍然可以完美工作(當然,因爲這是一個內存映射緩衝區,我假設.getInt()從磁盤獲取數據,這意味着數據已被刷新到磁盤了。

  2. 是在.force()方法的阻塞方法?

  3. 是一個阻塞方法的synchronized塊?

  4. 有使用或不調用.force(巨大的性能差異)方法手動調用.force()的好處是什麼?我們應該在哪種情況下使用它?我假設不調用它,數據仍然會被寫到磁盤後面的場景中

  5. 如果我們需要調用.force(),將從另一個線程調用它有助於提高性能?由於同步問題會損壞數據嗎?

    import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode;

公共類主要{

public static void main(String[] args) throws IOException { 
    System.out.println("start"); 

    RandomAccessFile raf = new RandomAccessFile("test.map", "rw"); 
    FileChannel fc = raf.getChannel(); 
    MappedByteBuffer mbb = fc.map(MapMode.READ_WRITE, 0, 2000000); 

    int total = 0; 
    long startTime = System.currentTimeMillis(); 
    for (int i = 0; i < 2000000; i += 4) { 
     mbb.putInt(i, i); 
     //mbb.force(); 
     total += mbb.getInt(i); 
    } 
    long stopTime = System.currentTimeMillis(); 

    System.out.println(total); 
    System.out.println(stopTime - startTime); 
    System.out.println("stop"); 
} 

}

+0

JDK的版本? (並不是說它真的發生了很大的變化) – 2010-11-04 13:06:05

+0

我沒有看到會有什麼不同。 – EJP 2010-11-04 13:10:20

+0

在查看Javadoc後無:-) – 2010-11-04 13:39:52

回答

3
  1. 你應該把它只有當你有極端事務需求,即要實現一個數據庫。 getInt()從內存中讀取:操作系統將文件分頁和分頁。

  2. 沒有指定。

  3. 如果指定了同步方法。它與它們是否阻擋無關。

  4. 參見(1)。數據仍然會被編寫,但是在操作系統的時間而不是你的。 (1)。我懷疑它,但請參閱(2),我懷疑你需要調用它,參見(1)。

+0

Gah,應該先看到你的回答,並表示道歉,說幾乎相同的東西:)。 – 2010-11-04 13:39:17

+0

我有一個問題,如果我不調用強制(),當我調用putInt或getInt時,是否有該文件的任何io操作? – Jaskey 2016-10-20 08:14:43

2

OK,把我的答案用一粒鹽(我不是一個NIO專家)

1)的putInt(i, i)將會寫入MappedByteBuffer(MBB),這是在內存中運行系統會在需要時將該值轉換爲實際的基礎文件(test.map)。

使用force()告訴操作系統傳輸數據'現在'(如果您有另一個需要從該文件讀取的進程,這可能很有用)。

您的getInt(i)正在讀取來自MappedByteBuffer(MBGB)的值,如果您使用force()那麼您知道底層文件與該內存緩衝區同步。

機會是作爲Java 7 NIO.2東西開始暗示能夠做這樣的事情,你不需要使用force()

2)不知道,我覺得是以非阻塞的方式。目前我仍在研究這個問題。

3.)這些是兩個不同的問題。我建議看看Doug Lea的書:-)。 4.)作爲1.)狀態,force()會告訴操作系統寫'現在',否則操作系統會在感覺到它時寫入。

+0

我有一個問題,當強制執行時,對putInt()有任何影響? ,是否把int必須等待force()來完成,或者'force()'是否影響到putInt()? – Jaskey 2016-10-20 08:28:52

1

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6816049

力()是在Windows上沒用。很可怕的錯誤。

+0

除了Yao的評論/回答,對於大多數用戶來說這個實現已經足夠好了,這個鏈接的bug已經在JRE 7 build 118中得到修復,當前的JVM不受影響。 – 2016-01-19 00:37:10

3

MappedByteBuffer.force()是不是在Windows中沒用。我使用http://technet.microsoft.com/en-us/sysinternals/bb896645的「Process Monitor」工具來監視文件訪問。根據日誌記錄,MappedByteBuffer.force()將立即調用Windows API WriteFile()非高速緩存同步模式。可靠性應該與FileChannel.force()類似,它將立即調用Windows API FlushFileBuffers()來寫入文件。因此,MappedByteBuffer.force()對於大多數用法足夠可靠。使用Java 1.6.0_24測試Windows 7 64位。

+1

這不提供問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 - [來自評論](/ review/low-quality-posts/10941104) – AtheistP3ace 2016-01-19 00:58:56

+0

我沒有權利在帖子下方添加評論,當我寫這篇文章。這就是爲什麼我創建了一個新帖子。 – Yao 2016-04-08 02:25:22

相關問題