mappingsize 或 limit 如何影响 MappedByteBuffer 性能?
How mappingsize or limit affects MappedByteBuffer performance?
我正在处理大文件,我正在使用 MappedByteBuffer 进行读写操作。我有点缺乏知识,所以我想知道一些事情。
MappedByteBuffer buf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size);
我知道 ByteBuffer 的大小限制是 Integer.MAX_VALUE 那么我应该如何设置 MappedByteBuffer 的大小?我应该用小块还是Integer.MAX_VALUE?
那么,如果我增加映射大小,我的应用程序读写性能是否也会提高?
虽然这个大小增加了,但我的内存使用量也在增加吗?我想知道这是因为我正在创建多个文件来读写。所以也许如果一个文件分配 2gb 的内存,如果我有 6 个文件我需要 12gb 的内存或者我的想法是完全错误的。
是和JVM -Xmx有关还是我的物理内存有关?
这是我的用法:
List<MappedByteBuffer> mappings = new ArrayList<MappedByteBuffer>();
int mSize = 25;
long MAPPING_SIZE = 1 << mSize;
File file = File.createTempFile("test", ".dat");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
ByteOrder byteOrder = java.nio.ByteOrder.nativeOrder(); // "LITTLE_ENDIAN";
try {
long size = 8L * width * height;
for (long offset = 0; offset < size; offset += MAPPING_SIZE) {
long size2 = Math.min(size - offset, MAPPING_SIZE);
MappedByteBuffer buf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size2);
buf.order(byteOrder);
mappings.add(buf);
}
}
关于第二点你是对的。
第三点,与你的物理内存有关。
首先,这取决于您的用例,但如果您使用 Integer.MAX_VALUE,您会发现您的应用程序有些滞后。
使用 MappedByteBuffer,我们需要确保文件适合内存。否则,我们可以填满整个内存,结果 运行 进入常见的 OutOfMemoryException。我们可以通过只加载文件的一部分来克服这个问题。
MappedByteBuffer 使用 JVM 内存创建虚拟内存映射。文件内容加载到虚拟内存而不是堆中。
这里有几个链接可以帮助您更好地理解。
简短回答是,如果您知道您的文件将比 2g 大很多。唯一的缺点是您的磁盘 space 使用情况:如果您使用较大的增量,如果 size
不是 MAPPING_SIZE
的倍数,则浪费的磁盘 space 的数量会更大.
只有您的虚拟内存使用量在增加。除非你在 32 位机器上,否则这应该不是问题。 Linux 上的最大虚拟内存为 128TiB,因此您还有一些空间。如果您需要比这更多的虚拟内存,您将需要寻求另一种解决方案。
内存映射文件使用页面缓存:OS 只会在使用时将文件页面 [1] 逐页加载到物理内存中,并在可用物理 RAM 变紧时卸载这些页面。
没有。参见 2.
对于一些额外的资源,这里有一个关于页面缓存如何工作的很好的总结:Page Cache, the Affair Between Memory and Files
[1]:一个page是OS级的内存单元,一般为4KiB
我正在处理大文件,我正在使用 MappedByteBuffer 进行读写操作。我有点缺乏知识,所以我想知道一些事情。
MappedByteBuffer buf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size);
我知道 ByteBuffer 的大小限制是 Integer.MAX_VALUE 那么我应该如何设置 MappedByteBuffer 的大小?我应该用小块还是Integer.MAX_VALUE?
那么,如果我增加映射大小,我的应用程序读写性能是否也会提高?
虽然这个大小增加了,但我的内存使用量也在增加吗?我想知道这是因为我正在创建多个文件来读写。所以也许如果一个文件分配 2gb 的内存,如果我有 6 个文件我需要 12gb 的内存或者我的想法是完全错误的。
是和JVM -Xmx有关还是我的物理内存有关?
这是我的用法:
List<MappedByteBuffer> mappings = new ArrayList<MappedByteBuffer>();
int mSize = 25;
long MAPPING_SIZE = 1 << mSize;
File file = File.createTempFile("test", ".dat");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
ByteOrder byteOrder = java.nio.ByteOrder.nativeOrder(); // "LITTLE_ENDIAN";
try {
long size = 8L * width * height;
for (long offset = 0; offset < size; offset += MAPPING_SIZE) {
long size2 = Math.min(size - offset, MAPPING_SIZE);
MappedByteBuffer buf = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size2);
buf.order(byteOrder);
mappings.add(buf);
}
}
关于第二点你是对的。 第三点,与你的物理内存有关。 首先,这取决于您的用例,但如果您使用 Integer.MAX_VALUE,您会发现您的应用程序有些滞后。
使用 MappedByteBuffer,我们需要确保文件适合内存。否则,我们可以填满整个内存,结果 运行 进入常见的 OutOfMemoryException。我们可以通过只加载文件的一部分来克服这个问题。
MappedByteBuffer 使用 JVM 内存创建虚拟内存映射。文件内容加载到虚拟内存而不是堆中。
这里有几个链接可以帮助您更好地理解。
简短回答是,如果您知道您的文件将比 2g 大很多。唯一的缺点是您的磁盘 space 使用情况:如果您使用较大的增量,如果
size
不是MAPPING_SIZE
的倍数,则浪费的磁盘 space 的数量会更大.只有您的虚拟内存使用量在增加。除非你在 32 位机器上,否则这应该不是问题。 Linux 上的最大虚拟内存为 128TiB,因此您还有一些空间。如果您需要比这更多的虚拟内存,您将需要寻求另一种解决方案。 内存映射文件使用页面缓存:OS 只会在使用时将文件页面 [1] 逐页加载到物理内存中,并在可用物理 RAM 变紧时卸载这些页面。
没有。参见 2.
对于一些额外的资源,这里有一个关于页面缓存如何工作的很好的总结:Page Cache, the Affair Between Memory and Files
[1]:一个page是OS级的内存单元,一般为4KiB