gpt4 book ai didi

java - 截断内存映射文件

转载 作者:IT王子 更新时间:2023-10-28 23:54:50 26 4
gpt4 key购买 nike

我正在为索引文件使用内存映射 IO,但问题是如果文件大部分是空的,我无法调整文件大小。

之前的某处:

MappedByteBuffer map = raf.getChannel().map(MapMode.READ_WRITE, 0, 1 << 30);
raf.close();
// use map
map.force();
map = null;

调整大小:

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();
}
}

当使用 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();
}
}

当然它依赖于 JVM,如果 Sun 决定更改 sun.nio.ch.DirectBuffer,您应该准备好修复您的代码或 sun.misc.Cleaner以一种不兼容的方式(但实际上我不相信这会发生)。

关于java - 截断内存映射文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5989267/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com