Recently we had a problem with our Java web service. It ran a computationally expensive and memory intensive program that often ran out of memory for no apparent reason. Even though the files it was dealing with were around 70K each and it had 1GB of heap it ran and ran for 5 minutes and then failed with an out of memory error. So I ran the same program with exactly the same JVM settings on my MacOSX laptop with the same data and hey presto it ran flawlessly in one minute. Then I ran JProfiler on the two instances of the program - on OSX and Linux (Ubuntu 12.04). The JVM 1.6 settings were -Xmx1024m -Xss8m in both cases. Here is the OSX memory profile:
What seems to be going on here is that the garbage collector isn't being called often enough on Linux. And I know that the JVMs are not exactly the same but I did install the Oracle JVM, not the default OpenJDK on Linux but it made no difference. On the Oracle site they suggest trying the -Xincgc setting (incremental garbage collector). I added this to the JVM on Linux and magically the memory profile looked exactly like the one on OSX. It seems that those Apple guys aren't so dumb after all when it comes to tuning Java and their setup simply works better - for me at least. But you can get the same thing on Linux by adding one setting to your java invocation.