我需要使用 GC 无法控制的可用 RAM 中的空间。我读了几篇同样的文章,介绍了两种方法。它们在以下代码中指定。
package com.directmemory;
导入 java.lang.reflect.Field;导入 java.nio.ByteBuffer;
导入 sun.misc.Unsafe;
公共类 DirectMemoryTest {
public static void main(String[] args) {
//Approach 1
ByteBuffer directByteBuffer = ByteBuffer.allocateDirect(8);
directByteBuffer.putDouble(1.0);
directByteBuffer.flip();
System.out.println(directByteBuffer.getDouble());
//Approach 2
Unsafe unsafe = getUnsafe();
long pointer = unsafe.allocateMemory(8);
unsafe.putDouble(pointer, 2.0);
unsafe.putDouble(pointer+8, 3.0);
System.out.println(unsafe.getDouble(pointer));
System.out.println(unsafe.getDouble(pointer+8));
System.out.println(unsafe.getDouble(pointer+16));
}
public static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
我有一些问题
1)为什么我应该注意代码中提到的方法1,因为根据我的理解 ByteBuffer.allocateDirect() 不能返回一个存储容量大于 2GB 的缓冲区?因此,如果我的要求是存储 3 GB 的数据,我必须创建一个新缓冲区并将数据存储在那里,这意味着除了存储数据之外,我还有识别相应缓冲区的额外责任(在 'n 列表之外) ' 缓冲区),它维护指向直接内存的指针。
2)方法2不是比方法1快一点,因为我不必先找到缓冲区然后再找到数据,我只需要一个对象字段的索引机制并使用getDouble / getInt方法并传递绝对值地址 ?
3)直接内存的分配(说堆内存是否正确?)与PID有关吗?如果在一台机器上,我有 2 个 java 进程,PID 1 和 PID 2 中的 allocateMemory 调用让我永远不会使用相交的内存块?
4) 为什么最后一个 sysout 语句没有导致 0.0 ?这个想法是每个双精度都使用 8 个字节,所以我将 1.0 存储在 allocateMemory 返回的地址,比如地址 = 1,地址 1+8 的 2.0 是 9,然后停止。那么默认值不应该是 0.0 吗?