<br><font size=2 face="sans-serif">Hello,</font>
<br>
<br><font size=2 face="sans-serif">I have a problem I was hoping with which
I need some advice.</font>
<br>
<br><font size=2 face="sans-serif">We wrote a custom JNI library for file
I/O that sits underneath the Java NIO FileChannel. One of our driving
requirements is highly performant file I/O. We achieved this by doing
DMA I/O from large direct memory aligned buffers. The JNI is very
trivial - it just takes a buffer and performs the appropriate system call
based on the parameters given to it. 100% of the logic for calculating
offsets, buffer management, etc. is all in our implementation of java.nio.FileChannel.</font>
<br>
<br><font size=2 face="sans-serif">Here's our problem: We have requirements
to respond to some messages in as little as 250 ms. During this time,
we're doing file writes of 128 MB that take around 200 ms. When GC
kicks in, it tries to pause all threads. Because the DMA write is
non-interruptable, GC waits for the I/O to complete before being able to
pause the thread & run. That means that GC can take well over
200 ms putting us in grave danger of missing our timelines. Worse,
there is always the chance the write will hang due to a bad filesystem.
We've seen this cause the JVM to hang indefinitely forcing us to
cycle the process.</font>
<br>
<br><font size=2 face="sans-serif">Unless we find a solution that allows
GC to continue while doing this I/O, we will convert all the code to C++.
While that might solve our timeline for that particular process,
we have many less performance critical processes that use our JNI FileChannel
libraries that would hang if a filesystem goes bad.</font>
<br>
<br><font size=2 face="sans-serif">We've tweaked the file system device
timeouts down to a minimum, but they are still very high (on the order
of several seconds to minutes). It would be nice if the JVM had a
similar timeout for pausing threads, i.e., where the pause times out after
X number of milliseconds. We'd be willing to sacrifice a larger heap
size and postpone GC in the hopes that the next time it ran GC, we wouldn't
be in the middle of a non-interruptable system call.</font>
<br>
<br><font size=2 face="sans-serif">The only solution being batted around
here is pushing the system calls out of Java threads and into native threads.
The JNI call would push the info for the I/O call onto a native C++
queue where a small number of native threads (3?) would pull the data off
the queue and perform the actual system call. The trick is finding
an implementation where the Java thread blocked waiting on a response from
the native thread is interruptible. All this assumes GC doesn't try
to pause native threads. We thought about using pthreads, but were
concerned about its signal interaction with the JVM. So, we're leaning
towards using pipes to push data from one thread to another.</font>
<br>
<br><font size=2 face="sans-serif">If you have any suggestions or advice,
we are desperate for your wisdom.</font>
<br>
<br><font size=2 face="sans-serif">Thanks!<br>
</font>
<br><font size=2 face="sans-serif"><br>
Mark Maxey<br>
Raytheon, Garland<br>
580/2/P22-1<br>
(972)205-5760<br>
Mark_R_Maxey@Raytheon.com</font>