我知道在Java中这是一个奇怪的问题, 但有没有办法让Java动态内存分配与某些对齐约束对齐? 例如,是否可以动态分配与页面大小对齐的对象?
我想这样做的原因是因为我将通过JNI接口从本机代码访问Java对象,而本机代码库需要对齐对象。
感谢。
答案 0 :(得分:7)
不,不可能。请记住,Java中堆上的对象可以在垃圾回收期间移动。你有一些选择:
答案 1 :(得分:5)
有关java中直接内存对齐的更广泛讨论,请参阅此blog post,其中也涵盖了您的要求。总结一下:
我会建议你不要去重复分配,直到你找到正确的地址。这对你的软件来说非常糟糕。如果您计划重复获取地址,我建议您在计划使用上述反射方法时对其进行缓存。或者,使用不安全的帖子中列出的方法来获取地址字段的值。
答案 2 :(得分:2)
没有漂亮的选择,所以这里是丑陋的选择:
如果您使用的是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访问数据,请使用缓冲区。要在JNI中访问,请将地址强制转换为指针。两者都会看到/更改相同的数据。
地址应该是页面对齐的,但为了确保这一点,你可以分配两个页面(肯定会有足够的空间用于完整的对齐页面)。然后在页面上对齐地址并对ByteBuffer访问应用偏移量。
适用于任何VM的缓冲区分配和本机调用的另一个选项是使用JNAs Memory类:http://jna.java.net/javadoc/com/sun/jna/Memory.html。不要害怕 com.sun 包。它是开源的和LGPL。