我试图实施一种共享缓存在两个或更多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)
{
}
  1. 输出上述代码0字节的直接内存存使用情况(File.txt 1GB)。但是,如果我取消。

    ByteBuffer buf6 = ByteBuffer.allocateDirect(100000000);
    

    我得到一个直接存储器使用的100MB.不能理解这是为什么那么,为什么我没有得到任何直接存储器的使用在第一个地方(即当线是出评论)

  2. 虽然直接内存使用情况是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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top