我知道在 Java 中这是一个奇怪的问题,但是有没有办法让 Java 动态内存分配与一些对齐约束对齐?例如,是否可以动态分配与页面大小对齐的对象?
我之所以要这样做,是因为我要通过JNI接口从native代码访问Java对象,而native代码库要求对象对齐。
谢谢。
我知道在 Java 中这是一个奇怪的问题,但是有没有办法让 Java 动态内存分配与一些对齐约束对齐?例如,是否可以动态分配与页面大小对齐的对象?
我之所以要这样做,是因为我要通过JNI接口从native代码访问Java对象,而native代码库要求对象对齐。
谢谢。
不,这是不可能的。请记住,Java 中堆上的对象可以在垃圾回收期间四处移动。你有一些选择:
有关Java 中直接内存对齐的更广泛讨论,请参阅此博客文章,这也涵盖了您的要求。总结一下:
我建议您在找到正确的地址之前不要进行重复分配。这对您的软件非常不利。如果您打算重复获取地址,如果您打算使用上述反射方法,我建议您将其缓存。或者使用文章中概述的方法使用 Unsafe 来获取地址字段的值。
没有漂亮的选择,所以这里是丑陋的:
如果您使用的是 Sun(现在是 Oracle)JRE 5.0 或 6.0,则可以使用以下内容:
ByteBuffer buffer = ByteBuffer.allocateDirect(pageSize);
Method getAddress = buffer.getClass().getMethod("address");
long address = getAddress.invoke(buffer);
// and now send address to JNI
要在 Java 中访问数据,请使用buffer。要在 JNI 中访问,请将地址转换为指针。两者都会看到/更改相同的数据。
该地址应该是页面对齐的,但为了确保这一点,您可以分配两个页面(肯定会有足够的空间用于完全对齐的页面)。然后对齐页面上的地址并将偏移量应用于 ByteBuffer 访问。
另一个适用于任何 VM 的缓冲区分配和本机调用选项是使用 JNAs 内存类:http: //jna.java.net/javadoc/com/sun/jna/Memory.html。不要被com.sun包吓到。它是开源的和 LGPL。