这是一个工作样本.但请注意,因为您可能会因为不正确的Unsafe类使用而轻易崩溃JVM .
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class UnsafeTest {
public static void main(String... args) {
Unsafe unsafe = null;
try {
Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (sun.misc.Unsafe) field.get(null);
} catch (Exception e) {
throw new AssertionError(e);
}
int ten = 10;
byte size = 1;
long mem = unsafe.allocateMemory(size);
unsafe.putAddress(mem, ten);
long readValue = unsafe.getAddress(mem);
System.out.println("Val: " + readValue);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用ByteBuffer.allocateDirect()直接缓冲区而不是使用数组.它具有字段中的地址,并且该地址在ByteBuffer的生命周期内不会改变.直接ByteBuffer使用最小的堆空间.您可以使用反射获取地址.
您可以使用Unsafe获取地址,问题是GC可以随时移动它.对象未在内存中修复.
在JNI中,您可以使用特殊方法将数据复制到Java对象或从Java对象复制数据以避免此问题(以及其他问题)如果您希望在具有C代码的对象之间交换数据,我建议您使用这些方法.