【发布时间】:2014-03-11 23:13:26
【问题描述】:
我编写了一些使用映射文件缓冲区的 Posix 程序。一个简单的场景是将一个 1GB 的文件映射到内存中,然后用内容填满整个文件。
在程序执行期间几乎没有磁盘 IO,直到发生 msync 或 munmap 调用。
在完全相同的系统上,我用 Java 编写了在 Oracle JDK 7 上运行的等效程序,并注意到在整个程序执行过程中存在大量磁盘 IO 活动。
内存映射文件缓冲区在 JVM 中的实现方式有何不同?有没有办法推迟大规模的 IO 活动?
操作系统是 Linux 3.2 x64。
代码:
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class Main {
public static void main(String[] args) throws Exception {
long size = 1024 * 1048576;
RandomAccessFile raf= new RandomAccessFile("mmap1g", "rw");
FileChannel fc = raf.getChannel();
MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_WRITE, 0, size);
for(long i = 0; i < size; ++i)
buf.put((byte)1);
}
}
【问题讨论】:
-
这可能与您的编码方式有关。不看代码,是无法分辨的。
-
@NPE 如果您密切关注您的任何 mmap 程序,这是一个明显的现象。但我还是把代码放了。
-
您可以改写 long,但您只需要触摸每一页(每 4 KB)即可更快地弄脏数据。请参阅 MappedByteBuffer.load() 的实现,它所做的只是每 4 KB 读取一次。
-
你的 JVM 有多少内存用于内存映射?
-
@user2357112 JVM 不限制内存映射的使用。您可以将所有内存限制设置为几 MB,但仍会映射到 TB 的内存。
标签: java linux performance memory file-io