在Java中访问内存的最佳方法是什么,类似于mmap?

我正在研究需要与C应用程序通信的Java应用程序。 C应用程序使用共享内存和mmap进行通信,我需要Java应用程序才能访问相同的内存。

我的第一次尝试涉及使用JNI调用从共享内存中检索数据,但每次JNI调用的开销都会导致性能下降,所以我想要一种方法来获取Java中的内存并在Java端进行数据检索。

我的想法是我需要做以下事情:

  1. 使用一个JNI调用来获取我需要附加到的共享内存位置的位置
  2. 创建一个新的FileChannel()
  3. 使用该FileChannel使用map()创建MappedByteBuffer

这是最好的方法吗? 另外,我不确定如何实际创建FileChannel以指向正确的内存位置。

研究使用ByteBuffer.allocateDirect 。 显然,这些缓冲区可以通过JNI层传递给可以直接访问内存的本机代码。

有关提示,请参阅此页面 (如下所述)。

现在,JNI代码不仅可以发现在Java端使用ByteBuffer.allocateDirect()创建的缓冲区内的本机内存空间的地址,而且可以分配自己的内存(例如,使用malloc())然后调用返回JVM以将该内存空间包装在新的ByteBuffer对象中(执行此操作的JNI方法是NewDirectByteBuffer())。

我会写一个小的C模块mmaps共享内存和使用套接字允许另一个应用程序看到该内存(例如你的Java应用程序)

如果您同时拥有C和Java应用程序,它们可以通过控制台流进行通信 – 对于二进制数据而言很难,但可能。 我会交换共享内存以获得更多的消息传递方式 – 例如TCP / IP套接字对。

顺便问一下,传递什么样的数据以及它有多大?

难道你不能用一些本地方法编写Java类,用C编写本机方法实现来用mmap做你想做的事。 然后将其编译到本机库中,并使用LD_LIBRARY_PATH将其添加到运行时。 这将使您能够在没有JNI开销的情况下在Java中进行本机C调用(我认为)。

这里有一些教程: 链接

例如,您将编写一个Java类,例如:

 JMMap.java public class JMMap { public native void write(...) } 

然后对类文件运行javah以生成类似于:

 JMMap.h JNIEXPORT void JNICALL Java_JMMap_write(JNIEnv *, jobject); 

在.c文件中实现此function。 将其编译到库中。 将其添加到LD路径,然后只需调用Java函数。

如果您可以将数据保存到C中的文件中,然后从Java访问该文件,那将是最好的。 AFAIK你不能以你想要使用Java的方式指向内存。