有没有一种方法可以仅在Java中从指针创建直接ByteBuffer?

有没有一种方法可以仅在Java中从指针创建直接ByteBuffer?,java,jvm,bytebuffer,Java,Jvm,Bytebuffer,或者我必须有一个调用env->NewDirectByteBuffer(缓冲区,大小)的JNI帮助函数吗?我要做的是创建一个普通的DirectByteBuffer并更改它的地址 Field address = Buffer.class.getDeclaredField("address"); address.setAccessible(true); Field capacity = Buffer.class.getDeclaredField("capacity"); capacity.setAcc

或者我必须有一个调用env->NewDirectByteBuffer(缓冲区,大小)的JNI帮助函数吗?

我要做的是创建一个普通的DirectByteBuffer并更改它的地址

Field address = Buffer.class.getDeclaredField("address");
address.setAccessible(true);
Field capacity = Buffer.class.getDeclaredField("capacity");
capacity.setAccessible(true);

ByteBuffer bb = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder());
address.setLong(bb, addressYouWantToSet);
capacity.setInt(bb, theSizeOf);
从这一点上,您可以访问引用底层地址的ByteBuffer。我这样做是为了访问zero copy网络适配器上的内存,效果很好

您可以直接为您的地址创建一个DirectByteBuffer,但这更为模糊


另一种方法是使用不安全(这仅适用于OpenJDK/HotSpot JVM,并且以本机字节顺序)


你看过sun.misc.unsafe了吗?它允许您直接与内存进行交互。我看了一下,没有看到使用sun.misc.unsafe创建直接字节缓冲区的方法。我确实找到了一种通过反射创建DirectByteBuffer的方法。使用java.lang.Class.getDeclaredConstructor创建构造函数对象,将Accessable设置为true,并使用适当的参数调用newInstance。小janky,但是你不必写任何JNI代码。答案很好,但是我不得不对它进行一些修改,特别是Field address=Buffer.class.getDeclaredField(“address”)。因此,这里是对原始问题的后续,因为你仍然在关注。以这种方式清理附在ByteBuffer上的内存的最佳方法是什么?ByteBuffer将最终确定免费地址,还是呼叫者应该介入并清理分配?就这个问题而言,假设我已经编写了一个JNI库,其中包含了malloc和free的包装:)这可能是我自己的问题,因为我已经对它进行了更多的思考。@Erik谁创建了内存应该释放它。如果您需要调用一个特殊的方法,您需要设置一个清理器,它可以被确定地调用,或者当缓冲区处于GC状态时调用,如果您不这样做的话。@Erik在编年史字节中,我们有我们自己的64位内存包装器和附加功能。我们还提供了引用计数功能,允许按需释放内存,并在未释放内存时提供了一个清理器。感谢您的快速回复!我将阅读Cleaner(我是一名C程序员,被要求做Java的事情,试图快速启动)。
Unsafe.getByte(address);
Unsafe.getShort(address);
Unsafe.getInt(address);
Unsafe.getLong(address);