Skip to content

JVM Tuning

Lloyd Dilley edited this page Mar 1, 2015 · 1 revision

JVM Tuning

The following tips should help you squeeze more performance or efficiency out of your JVM. If you are using JRuby and RubIRCd is configured to use threaded mode, I recommend at least the following three JRuby arguments (-J allows you to pass arguments from jruby to the JVM):

jruby --fast --server -J-Djruby.thread.pool.enabled=true rubircd.rb

--fast
Makes several optimizations which can boost runtime performance. Using this option may also increase the time it takes for the program to start.

--server
This passes the "-server" option to the JVM which usually increases startup time, but results in better performance while the program is up and running. The server JVM is better suited for long-running applications. Aside from increased start-up time, the other disadvantage is that server mode typically uses more memory. You can work around these two potentially unfavorable conditions (if they *really* bother you) by using AoT (Ahead of Time) compilation with jrubyc (the JRuby compiler) and by reducing the amount of memory the JVM is allowed to use. See below for details on memory tuning.

-J-Djruby.thread.pool.enabled=true
Since spinning up new threads is expensive and then throwing them away afterward is a waste, this argument allows the pooling and reuse of threads.

Other Optimizations

-J-Xincgc
Use incremental garbage collection. Ordinarily, garbage collection occurs all at once at certain intervals. During that time, the program may pause until garbage collection is complete. Incremental garbage collection is more subtle and occurs gradually instead of all up front. This can make runtime smoother.

-J-Xss256K
Sets the stack size to an arbitrary amount. If you set this too low, you will get an error stating that the value is too small and to bump it up to at least 160K. 256K seems to be fine and saves me around 100M virtual size. Please let me know if any of you are experiencing problems with this setting.

-J-Xmn8M
Sets the heap space size for young/Eden garbage collection. This should be less than the -Xmx value.

-J-Xms16M
-J-Xmx64M
Sets the initial/minimum and maximum heap sizes. 16M should be fine here unless you receive a message on JVM start complaining that it is not enough. 64M is also a decent value. The maximum heap size can always be adjusted later if you get "java.lang.OutOfMemoryError: Java heap space" errors.

-J-XX:PermSize=16M
-J-XX:MaxPermSize=64M
Sets the initial/minimum and the maximum permanent heap space for perpetual class data. If you see "java.lang.OutOfMemoryError: PermGen space" and/or "Error: Your application exhausted PermGen area of the heap." then increase the MaxPermSize value. Note that MaxPermSize is in addition to the max heap size (-Xmx).

-J-XX:ThreadStackSize=128K
I recommend letting the JVM manage this parameter. I've found when setting it to something like 128K, the program uses more than 3x as much memory (436M versus 1520M virtual in my case.)

-J-XX:+UseCompressedOops
If using the 64-bit JVM, this option sets the max heap size to 32G (which is not a problem since RubIRCd uses well below that amount) and also represents 64-bit addresses on the heap in 32-bit format. The result is reduced memory usage.

-J-Djruby.compile.invokedynamic=true
If using Java 8 or certain versions of Java 7, enabling this option "greatly improves JRuby's performance" per https://github.com/jruby/jruby/wiki/PerformanceTuning.

AoT Compilation
You can optionally precompile RubIRCd using jrubyc. This is beyond the scope of the RubIRCd project however since we are focused on Ruby and not so much on Java (I do not currently plan on packaging up class and jar files.) More information on precompiling Ruby source into Java bytecode can be found here: https://github.com/jruby/jruby/wiki/JRubyCompiler.

Clone this wiki locally