差ByteBuffer。allocateDirect()和MappedByteBuffer.load()
-
22-07-2019 - |
题
我试图实施一种共享缓存在两个或更多Jvm通过存储器的映射一特定文件的使用 MappedByteBuffer
.从规范的我看到的,当我们使用 MappedByteBuffer.load()
它应当将数据加载到一个直接的缓冲区。我有几个问题。
我的代码::
RandomAccessFile file = new RandomAccessFile("file.txt","rw");
FileChannel fc = file.getChannel();
MappedByteBuffer buf5 = fc.map(MapMode.READ_WRITE, 0, fc.size());
//ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
buf5.load();
try
{
Class c = Class.forName("java.nio.Bits");
Field f = c.getDeclaredField("reservedMemory");
f.setAccessible(true);
long reservedMemory = f.getLong(null);
f = c.getDeclaredField("maxMemory");
f.setAccessible(true);
System.out.println(
"Direct Memory Usage: "+ reservedMemory +"/"+ f.getLong(null)+"\n");
}
catch (Throwable t)
{
}
输出上述代码0字节的直接内存存使用情况(File.txt 1GB)。但是,如果我取消。
ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
我得到一个直接存储器使用的100MB.不能理解这是为什么那么,为什么我没有得到任何直接存储器的使用在第一个地方(即当线是出评论)
虽然直接内存使用情况是0B为上述代码,我看到,驻地存储器(使用unix顶部)的过程中增加1GB。但如果我做了一个"自由m"的盒子,我看不到任何增加存储器的使用。
在这两种情况下,我有点困惑,因为那里的记忆结束了。
谢谢!
解决方案
直接ByteBuffers(那些分配使用的ByteBuffer。allocateDirect)不同MappedByteBuffers在,他们所代表的不同部分的内存和分配方式不同。直接ByteBuffers是一种访问的一块分配的存储器之外的JVM一般分配用 malloc 呼吁(虽然大多数实现将可能使用一个有效的板分配器).I.e。这只是一个指向一个方块的存储器。
一MappedByteBuffer表示部分分配使用的存储器 mmap 呼叫,这是用于执行存储器映I/O.因此MappedByteBuffers不登记他们利用存储在同样的方式直接ByteBuffer会。
因此,虽然两者都是"直接"中,他们所代表的存储器之外的JVM他们的目的是不同的。
此外,为了获得reservedMemory值你是沉思叫到一种内部方法的JVM,其执行是不受任何规范,因此没有保证什么,值回报。直接ByteBuffers可以分配从使用JNI NewDirectByteBuffer 呼叫的从C/C++(MappedByteBuffers可能使用此),这可能不会影响reservedMemory值,这可能仅改变了在使用Java ByteBuffer。allocateDirect.