Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared memory between C++ and Java processes

Tags:

My aim is to pass data from a C++ process to a Java process and then to receive a result back.

I have achieved this via a named pipe but I would prefer to share the data rather than passing or copying it, assuming the access would be faster.

Initially, I thought of creating a shared segment in C++ that I could write to and read with Java, but I'm not sure if this is possible via JNI, let alone safe.

I believe it's possible in Java to allocate the memory using ByteBuffer.allocateDirect and then use GetDirectBufferAddress to access the address in C++, but if I'm correct this is for native calls within JNI and I can't get this address in my C++ process?

Lost.

Many thanks in advance.

like image 740
Brent Campbell Avatar asked Mar 14 '13 16:03

Brent Campbell


People also ask

Does Java support shared memory?

You can share class data between Java™ Virtual Machines (JVMs) by storing it in a cache in shared memory. Sharing reduces the overall virtual storage consumption when more than one JVM shares a cache.

What memory is shared between processes?

What is shared memory? Shared memory is the fastest interprocess communication mechanism. The operating system maps a memory segment in the address space of several processes, so that several processes can read and write in that memory segment without calling operating system functions.

What is shared memory in Java?

Shared memory is a memory shared between two or more processes.

Can multiple processes share memory?

Processes don't share memory with other processes. Threads share memory with other threads of the same process.


1 Answers

If you have shared memory, for example using CreateFileMapping (Windows) or shmget (Unix), all you need is a native method on the Java side. Then you can create a ByteBuffer that directly accesses the shared memory using NewDirectByteBuffer like this:

JNIEXPORT jobject JNICALL Java_getSharedBuffer(JNIEnv* env, jobject caller) {     void* myBuffer;     int bufferLength; 

Now you have to get a pointer to the shared memory. On Windows you would use something like this:

    bufferLength = 1024; // assuming your buffer is 1024 bytes big     HANDLE mem = OpenFileMapping(FILE_MAP_READ, // assuming you only want to read            false, "MyBuffer"); // assuming your file mapping is called "MyBuffer"     myBuffer = MapViewOfFile(mem, FILE_MAP_READ, 0, 0, 0);     // don't forget to do UnmapViewOfFile when you're finished 

Now you can just create a ByteBuffer that is backed by this shared memory:

    // put it into a ByteBuffer so the java code can use it     return env->NewDirectByteBuffer(myBuffer, bufferLength); } 
like image 184
main-- Avatar answered Sep 28 '22 13:09

main--