rur*_*uni 12 java linux io memory-management memory-mapped-files
我正在使用内存映射IO作为索引文件,但问题是如果文件大部分为空,我无法调整文件大小.
之前的某个地方:
MappedByteBuffer map = raf.getChannel().map(MapMode.READ_WRITE, 0, 1 << 30);
raf.close();
// use map
map.force();
map = null;
Run Code Online (Sandbox Code Playgroud)
调整:
for (int c = 0; c < 100; c++) {
RandomAccessFile raf = new RandomAccessFile(indexFile, "rw");
try {
raf.setLength(newLen);
if (c > 0) LOG.warn("used " + c + " iterations to close mapped byte buffer");
return;
} catch (Exception e) {
System.gc();
Thread.sleep(10);
System.runFinalization();
Thread.sleep(10);
} finally {
raf.close();
}
}
Run Code Online (Sandbox Code Playgroud)
当使用Windows或Linux 32位时,我经常遇到解映问题,但在64位Linux生产环境中,一切似乎都没有警告,但文件保持原始大小.
任何人都可以解释为什么会发生这种情况和/或如何解决问题?
你的问题是,你正在使用不可靠的方法来关闭映射的字节缓冲区(一百调用System.gc()并System.runFinalization()不能保证你任何东西).遗憾的是,Java API中没有可靠的方法可以做到这一点,但是在Sun JVM上(也可能在其他一些方面),您可以使用以下代码:
public void unmapMmaped(ByteBuffer buffer) {
if (buffer instanceof sun.nio.ch.DirectBuffer) {
sun.misc.Cleaner cleaner = ((sun.nio.ch.DirectBuffer) buffer).cleaner();
cleaner.clean();
}
}
Run Code Online (Sandbox Code Playgroud)
当然它依赖于JVM,如果Sun决定改变sun.nio.ch.DirectBuffer或者sun.misc.Cleaner以不兼容的方式,你应该准备修复你的代码(但实际上我不相信这会发生).
| 归档时间: |
|
| 查看次数: |
2492 次 |
| 最近记录: |