After some investigation of the stack trace, I think that this appears to be a deadlock bug in com.sun.jna code where various classes in this package depend on each other, so if two threads both trigger class-loading of different classes in com.sun.jna then we can get a classloading deadlock, e.g. A depends on B and B depends on A then if both A and B are classloaded by different threads simultaneously then both can deadlock.
(We're not the only people to be affected by this issue, e.g. as reported in http://bugs.wuala.com/view.php?id=3871#c10332 )
The workaround suggested in wuala is to trigger classloading in a thread-safe fashion so that by the time we have multiple threads, all these classes are loaded.
e.g. A possible workaround would be for the slave (and probably the main Jenkins process) to do something like this:
try {
com.sun.jna.Structure.class.toString();
com.sun.jna.Native.class.toString();
} catch (ClassNotFoundException ex) {
}
during their start-up phase, before they start any new threads. That'll safely trigger classloading (if extra safety is desired, catch Throwable instead) thus avoiding classloading these deadlock-prone classes in a multi-threaded environment.
Note: As a result of this deadlock, the slave had hundreds of threads all trying to call the SwapSpaceMonitor. This suggests that the monitor process isn't waiting for calls to complete before triggering another. This didn't help.