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

时间:2009-07-14 13:50:50

标签: java memory

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

我的第一次尝试涉及使用JNI调用从共享内存中检索数据,但是每个JNI调用的开销都会导致性能下降,因此我想要一种方法来访问Java中的内存并在数据检索上进行数据检索。 Java方面。

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

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

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

5 个答案:

答案 0 :(得分:11)

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

有关提示,请参阅this page(引用如下)。

  

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

这里有一些教程:link

例如,您可以编写一个Java类,例如:

JMMap.java

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

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

的内容
JMMap.h

JNIEXPORT void JNICALL Java_JMMap_write(JNIEnv *, jobject);

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

答案 4 :(得分:-2)

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