Sun JVM の MappedByteBuffer は、途中でデバイスにアクセスできなくなると落ちるらしい。
という記事がikvmブログの記事にあった。
Running this on JDK 1.6 (x64) and removing the network cable during the sleep will result in an Internal Error in the VM. Not exactly what I had hoped for.
Interestingly, on IKVM doing the same results in a cli.System.Runtime.InteropServices.SEHException being thrown.
.NET Frameworkの方はちゃんと例外を投げるようになっているっぽい。
で、やってみた。
まずは Windows から Debian GNU/Linux で動いている Samba につなぎにいき、途中で samba を止める。
import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.MappedByteBuffer; public class MMapTest { public static void main(String[] args) throws Exception { FileChannel fc = new RandomAccessFile("\\\\roadrunner\\moriyoshi\\Desktop\\test.txt", "r").getChannel(); Thread.sleep(10000); MappedByteBuffer map = fc.map(FileChannel.MapMode.READ_ONLY, 0, 4096); System.out.println(map.get(8)); } }
結果:
C:\>java MMapTest # # An unexpected error has been detected by HotSpot Virtual Machine: # # EXCEPTION_IN_PAGE_ERROR (0xc0000006) at pc=0x6d783d0c, pid=3084, tid=3852 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode, sharing) # Problematic frame: # V [jvm.dll+0x113d0c] # # An error report file with more information is saved as hs_err_pid3084.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp #
ぎゃー、確かに落ちる。逆はどうだろう。mount.cifs でマウントしてやってみた。
Sun JVM:
% LANG=C java MMapTest Exception in thread "main" java.io.IOException: Input/output error at sun.nio.ch.FileChannelImpl.size0(Native Method) at sun.nio.ch.FileChannelImpl.size(FileChannelImpl.java:310) at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:728) at MMapTest.main(MMapTest.java:9)
% LANG=C java MMapTest Exception in thread "main" java.io.IOException: Input/output error at gnu.java.nio.channels.FileChannelImpl.mapImpl(libgcj.so.70) at gnu.java.nio.channels.FileChannelImpl.map(libgcj.so.70) at MMapTest.main(MMapTest.java:9)
smbfs の場合は、どの段階でかは分からないけど一定時間はブロックして (「刺さって」)、そのあとエラーを返すようになっていますね。今日は深追いするのはやめておこう。
ちなみに、このバグ、Bug #6415680として登録されていました。
追記: FileChannel.size() で落ちるか落ちないかが運命の境目と見た。smbfs でもなんとかして落としたい。