It started when an app we were developing started exhibiting some odd behaviour where a particular feature was taking much longer than it should. The app in question is pretty complex but we did the usual debugging to narrow down where the big delays were coming from. What we found was very odd.
long T = System.currentTimeMillis();
T = System.currentTimeMillis()-T;
if (T > waitNow*5) System.out.println("Overslept "+T+" > "+waitNow);
Overslept 10053 > 10
Searching For An Answer
At this point the most likely candidate was garbage collection. Garbage collection can stall all the threads in the JVM while it collects, depending on which collection method is used, and in some cases it can take quite a while. JConsole didn't show any garbage collection happening but some research led us to safe points (good overview here) and to these options to show what pauses the JVM was performing and why:
At this point we were down to very few options - either this was a JVM bug that was being triggered by something our application was doing or it was an OS level problem. Searching revealed nothing useful on either count.
The way this manifested is that OS X would at random points pause our app for anything up to 15 seconds and certain operations would seem to inexplicably take ages. Sleeps we were requesting from our thread in Java were taking longer because the entire JVM was being paused at what appeared to be fairly random intervals for long periods.
JWrapper Sends The Pain Train Packing
The focus of JWrapper is always to make life more simple for you and allow you to focus on developing cross platform apps instead of picking through OS-specific or JVM-specific issues that you weren't expecting - picking up the ball where Java has dropped it so that you don't have to.