在Java中使用内存映射文件时检测(写入)失败
生活随笔
收集整理的這篇文章主要介紹了
在Java中使用内存映射文件时检测(写入)失败
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
內(nèi)存映射文件是一個很好的并且經(jīng)常被忽視的工具。 我不會在這里詳細介紹它們的工作方式(使用 力 Google Luke!),但我將快速總結(jié)其優(yōu)勢:
- 操作系統(tǒng)提供的延遲加載和寫入緩存(您不必自己編寫,并且可以確信操作系統(tǒng)的性能良好)
- 易于讀取復(fù)雜的二進制數(shù)據(jù)(例如其中編碼有各種相對偏移量的二進制數(shù)據(jù))
- 可用作高性能IPC機制
- 即使您的進程崩潰(即使操作系統(tǒng)仍然存在)也可以寫入磁盤
- 因為不阻塞(操作系統(tǒng)提供了異步刷新)并且不需要進入內(nèi)核模式,所以寫入速度非常快
但是,由于所有這些異步性,我不禁要問:如果發(fā)生磁盤故障,會發(fā)生什么? 操作系統(tǒng)如何通知您的進程它無法將寫入的內(nèi)容寫入磁盤?
一點點搜索就找到了答案:
- 在Linux下,當(dāng)操作系統(tǒng)嘗試將內(nèi)存寫回到磁盤但失敗時, 您的進程將獲得SIGBUS 。
- 在Windows下,下次嘗試在文件句柄上調(diào)用OS函數(shù)時,會收到EXCEPTION_IN_PAGE_ERROR錯誤
為了確認信息,我準備了一個快速測試程序 ,將一個犧牲USB驅(qū)動器插入筆記本電腦并進行了一些測試。 結(jié)論是:
- 當(dāng)然,Linux會生成SIGBUS,并且Java(OpenJDK 1.7.0_51-b00)沒有針對它的處理程序,從而導(dǎo)致進程崩潰: # A fatal error has been detected by the Java Runtime Environment:
#
# SIGBUS (0x7) at pc=0x00007f9bb5042396, pid=26654, tid=140306951444224
#
# JRE version: OpenJDK Runtime Environment (7.0_51) (build 1.7.0_51-b00)
# Java VM: OpenJDK 64-Bit Server VM (24.45-b08 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# v ~StubRoutines::jlong_disjoint_arraycopy
從好的方面來說,您知道自從您的流程停止以來,出現(xiàn)了嚴重錯誤。 不利的一面是,您可能不會立即采取行動(除非您已經(jīng)閱讀了這篇文章)
- 如果您嘗試刷新文件,Linux也可以生成更多“傳統(tǒng)”錯誤情況,例如: Exception in thread "main" java.io.IOException: Input/output errorat sun.nio.ch.FileDispatcherImpl.force0(Native Method)at sun.nio.ch.FileDispatcherImpl.force(FileDispatcherImpl.java:76)at sun.nio.ch.FileChannelImpl.force(FileChannelImpl.java:376)at Main.main(Main.java:84)
- Windows僅在您再次對文件句柄進行操作時(例如,通過像在Linux中那樣將其分散化,但在創(chuàng)建新映射時也是如此)(在Linux中沒有這種體驗),會生成異常: Exception in thread "main" java.io.IOException: The volume for a file has been externally altered so that the opened file is no longer validat sun.nio.ch.FileDispatcherImpl.size0(Native Method)at sun.nio.ch.FileDispatcherImpl.size(FileDispatcherImpl.java:96)at sun.nio.ch.FileChannelImpl.size(FileChannelImpl.java:307)at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:849)at Main.main(Main.java:64)
結(jié)論:內(nèi)存映射文件很棒–就像一把鋒利的刀子一樣很棒:您可以非常快速地使用它們來完成偉大的事情,但是它們也可以使您感到吃驚。 如果由于其優(yōu)點而要使用內(nèi)存映射文件,則它們具有以下優(yōu)點:
- 準備崩潰。 制定一個計劃何時發(fā)生(熱備用,熱備用,什么都不做–這些都是有效的選項,但要事先決定)
- 如果要確保數(shù)據(jù)在磁盤上,請刷新它 。 當(dāng)返回時,您可以(幾乎)確定數(shù)據(jù)在磁盤上(我們不會在這里進入磁盤/控制器高速緩存或虛擬服務(wù)器的奇妙世界)。
翻譯自: https://www.javacodegeeks.com/2014/03/detecting-write-failures-when-using-memory-mapped-files-in-java.html
總結(jié)
以上是生活随笔為你收集整理的在Java中使用内存映射文件时检测(写入)失败的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vcard导入安卓 乱码(vcard导入
- 下一篇: linux文件夹的大小排序(linux文