none
Inter Process communication with a windows Java application RRS feed

  • Question

  • I need to have two very big legacy real time applications - one written in Java and the other in C# to communicate with each other.

    Both are running on the same fairly strong multi core windows machine.

    They need to constantly communicate - passing several thousand pieces of information between each other every second.

    Each piece of information is from a few bytes to about a hundred bytes long.

    The primary concern is low latency.

    Of the many schemes for Inter Process comunications - what would have the lowest latency?

    Thursday, June 11, 2015 9:42 AM

All replies

  • Anonymous Pipes are probably as low-latency as it gets: https://msdn.microsoft.com/en-us/library/bb546102(v=vs.110).aspx

    Sockets are also low-latency but they are slower than anonymous pipes: http://stackoverflow.com/questions/6175209/low-latency-ipc-between-c-and-java

    Both processes can also use the same shared memory instead of communicate with each other: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx

    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question.

    Thursday, June 11, 2015 11:00 AM
  • Thanks

    I looked them up and if I understand correctly they seem to still have operating system overhead for every interprocess method call.

    I then saw this about c# unsafe pointers:

    https://msdn.microsoft.com/en-us/library/t2yzs44b.aspx

    Could this be a better approach? Does Java support something like this on the other end?


    • Edited by LShatzman Thursday, June 11, 2015 2:49 PM
    Thursday, June 11, 2015 2:41 PM
  • >>Could this be a better approach?

    No. Each process creates its own memory address space and a pointer is basically an address in that specific address space. So just forget about using native pointers to communicate between two separate processes and use any of the three techniques mentioned above.


    Please remember to close your threads by marking all helpful posts as answer and then start a new thread if you have a new question.

    Thursday, June 11, 2015 2:49 PM
  • You ask this like if memory managment is still done likewise in 1955. Currently program memory constantly swaps over the memory map. 

    But maybe you can find a way to fix the memory fixed somewhere, never heard of that in 2015, in my perception that was why the pipes where invented otherwise they never had done.


    Success
    Cor


    Thursday, June 11, 2015 2:55 PM
  •  

    Thanks Cor, Magnus,

    1955 was a very good year for wine and Rock n Roll...

    Seriously -

    I'm an algorithms guy - not so much system or languages - so pardon my ignorance

    I'm still hoping for a solution that does not involve context switching or significant system overhead for every cross language method call (thousands per second).

    I thought about using J# - but realise it’s on its way to be obsolete.

    I then came across this -

    https://en.wikipedia.org/wiki/IKVM.NET

    Your thoughts?


    • Edited by LShatzman Monday, June 15, 2015 9:02 AM
    Monday, June 15, 2015 9:01 AM
  • Actually if you're asking about IPC in C++ and C#, SharedMemory would have been valid answer. (.NET runtime provides mechanism to pin memory block(s) so it's possible. Just remember to create two regions - one for read and one for write to both side - to avoid race condition in lock-free fashion)

    However, to punch hole in Java to let it use Shared Memory you'll have to use JNI, which has even greater overhead than TCP socket (In fact that makes it C# <-> C++ <-> Java, with 2 security border transversal overhead). That makes it undesirable for your situation.

    Monday, June 15, 2015 9:21 AM
    Answerer
  • Cheong,

    I thought I was learning something new. But in my opinion is your link is not about a mechanism to pin memory block inside the computer. It is about save if from the GC to be released.

    This is the situation I'm writing about in OS systems which came after (or in mainframe before that) for instance MS Dos

    https://en.wikipedia.org/wiki/Virtual_memory 


    Success
    Cor

    Monday, June 15, 2015 10:30 AM
  • I think if both application are on the same machine the fastest option is memory mapped file (MemoryMappedFile). I don't know if Java has support for this, else it think pipes or a message queue is next fastest option.

    Note that a memory mapped file comes without any form of synchronization or fixed format of exchanging data, so it will be a complex task.

    Monday, June 15, 2015 12:20 PM
  • what would be reaonable results?

    With named pipes we got 80 micro secs for a call without parmaters to a mathod that does nothing, and 120 micro for a call with 10 paramters - some of arrays, totalling about 100 bytes, also for a method that does nothing.

    Is this what there is?

    Obviously it depands on the specific machine, processor speed etc... but for a middle of the line 2 year old computer - is this the ball park?

    We will also try shared memory and see if its better.

    Monday, June 15, 2015 12:41 PM
  • With pipes you have kernel moving the data between the two processes. So that will introduce some delay. I have no idea how much exactly, but 80 msec seems possible.

    Here is an overview of IPC. Here some timing for different methods.

    Monday, June 15, 2015 1:05 PM
  • Oh sorry, the link I copy and pasted is incorrect.

    http://blogs.msdn.com/b/clyon/archive/2004/09/17/230985.aspx

    It's essential that .NET runtime provides method to pin memory. If not it would have been dangerous to perform direct stride manipulation to HBitmap.

    Tuesday, June 16, 2015 1:05 AM
    Answerer
  • Talking about JNI, I found one interesting project here.

    Wonder how well (or not) does it perform...

    Tuesday, June 16, 2015 1:12 AM
    Answerer
  • Thanks Cheong

    Jni4Net was our first solution - but the performance was not good.

    Looking at the pinned memory option seems like an interesting avenue.

    Supose you pin memory in the .Net side. Pass the address to the Java side.  Use the first bit in the the shared memory as a flag. When its 0 it means the shared memory is controlled by the .Net side. When the .Net finishes the write to the space - it switches the flag to 1. The Java then takes control.

    the .Net process runs with a loop of the form

    while (flag==1) {}

    DoSomething()

    flag = 0

    and the Java has the same loop with flag==0

    Could this work?

    Tuesday, June 16, 2015 5:53 AM
  • The problem is more on Java side. JNI seems to be the only way for JVM sandboxed Java program to access bare metal of the underlying system. But using JNI will require the processes to transverse across multiple security boundaries, which will trigger security checks on system and antivirus etc. That's why it's going to be a slow one.

    Therefore, as I'm said in my first reply here, when you're asking for performance, TCP socket or Pipes will be better choices here.

    P.S.: It's like using COM+ Interop to set cells in Excel. When you attempt to set 2000+ cells in one go with Cell.Value to individual cell in VBA, the time lag is going to be very noticable. If you use Range.Value to set array to worksheet in one call instead, the process time would be instantaneous.

    If you want to increase the performance, try set a larger theshold in buffer to read lots of data in one time, then parse the data into tokens inside Java/C# respectively to minimize the overhead.



    Tuesday, June 16, 2015 6:07 AM
    Answerer
  • are there examples of shared memory between Java and .Net ?

    I've only been able to find examples of memory mapped files within each language - but not between processes of different languages.

    Tuesday, June 16, 2015 2:21 PM
  • >I've only been able to find examples of memory mapped files within each language

    That is the mechanism.  Memory Mapped Files is how you share memory between processes on Windows.  You still need a kernel synchronization object to protect reading and writing the shared memory. 

    >I'm still hoping for a solution that does not involve context switching or significant system overhead for every cross language method call (thousands per second).

    The only way to avoid context switching is to run both the Java and .NET applications in the same process, which contradicts your stated requirement of having separate applications.

    David


    David http://blogs.msdn.com/b/dbrowne/

    Tuesday, June 16, 2015 4:29 PM