我正在努力理解sun.misc.Unsafe的文档 - 我想因为它不适合一般用途,没有人真的为让它变得可读而烦恼 - 但实际上我真的需要一种方法来查找地址数组中的元素(以便我可以将指针传递给本机代码)。有没有人有任何工作代码这样做?它可靠吗?
答案 0 :(得分:6)
这是一份工作样本。但是请小心,因为您可能会因为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);
}
}
答案 1 :(得分:6)
您可以使用ByteBuffer.allocateDirect()直接缓冲区,而不是使用数组。它具有字段中的地址,并且该地址在ByteBuffer的生命周期内不会改变。直接ByteBuffer使用最小的堆空间。您可以使用反射获取地址。
您可以使用Unsafe获取地址,问题是GC可以随时移动它。对象没有在内存中修复。
在JNI中,您可以使用特殊方法将数据复制到Java对象或从Java对象复制数据以避免此问题(以及其他问题)如果您想在具有C代码的对象之间交换数据,我建议您使用这些方法。
答案 2 :(得分:1)
为什么呢? JNI中有很多用于处理Java数组内容的工具。您不需要使用下周可能不存在的未记录的内部Sun类。