Forkable OpenJDK...is it madness?

Charles Oliver Nutter headius at headius.com
Tue Nov 29 00:12:47 PST 2011


Ok, hypothetical situation. What if a patch were crafted for OpenJDK
that could make it possible to safely fork(2) the JVM process. What
would it look like?

Obviously VM-critical threads would have to be restarted. Such a thing
is certainly possible; the Rubinius VM maintains background threads
for JIT requests, etc, and before forking forces them to a safe point.
After forking, they are resumed at with their original state. Could
this be done for the OpenJDK worker threads?

On a JVM I have just started, running jruby -e "sleep", I see the
following non-userland threads:

* DispatchQueue_1: com.apple.main-thread  (serial)

This is presumably the thread started up to handle Cocoa events. I
assume there would be a way to re-start it on the other side.

* The main thread

This is the actual JVM "main" thread, and on my trace the stack tops
out in the "sleep" monitor. We can assume this is the thread we want
to survive forking.

* Eight GC threads

Possible to force them to a safe point and re-launch on the other
side? The stacks they're sitting on are not very deep...

* An unidentifier thread

It looks like this...I'm not sure what this one is doing:

          2597 java_start(Thread*)
            2597 VMThread::run()
              2597 VMThread::loop()
                2597 Monitor::wait(bool, long, bool)
                  2597 Monitor::IWait(Thread*, long long)
                    2597 os::PlatformEvent::park(long long)
                      2597 _pthread_cond_wait
                        2597 __semwait_signal

* Java: Reference Handler

The java.lang.ref handler. Presumably this could also be restarted,
since normally it sits there doing nothing...just waiting for work.

* Java: Finalizer

Again, a thread that normally does no work and could presumably be restarted.

* Java: Signal Dispatcher

This is certainly trickier, but I assume the same signal handling
logic that works in the parent could be restarted in the child without
a great deal of effort.

* Two Java: C2 CompilerThread0

Normally not doing anything; presumably could be restarted.

* Java: Service Thread
* Another unknown thread

These looks similar to the unknown thread above. I am guessing these
threads are more OS X-specific stuff...

...

So, most of the threads in question seem like they could be paused,
saved off in some way, and restarted on the other side. Of course it's
not that simple...I assume there's on-stack state that would need to
be translated and bootstrapped in the child. I also assume the JVM has
some intimate knowledge of memory layout that might go all wacky in
the presence of fork. But is something like this feasible in theory?

I ask because one of the biggest complaints from JRuby users is the
inability to fork...not just for doing fork+exec-style process
launching, but for initializing some state and preforking children.

And JRuby's not alone. Dalvik supports forking, which is a large part
of why it's able to boot small Java applications so darn quickly; the
base Dalvik process has already initialized a bunch of VM and Android
state, and the foked child just boots application-specific logic.

I'm interested in finding a way to make this happen.

- Charlie


More information about the mlvm-dev mailing list