Performance Tuning
From JRubyWiki
JRuby supports a number of options to help you tune performance. They range from turning on experimental features to turning off inefficient emulations of Ruby features. This document describes these options and their effects.
Contents |
Tuning the compiler
JRuby's compiler can be enabled in JIT mode or specified to run before execution. See JRuby Compiler for more details.
ObjectSpace
Disabling ObjectSpace
ObjectSpace has been disabled by default since 1.1b1. To reenable Objectspace, use the +O flag. The following is true for previous versions of JRuby.
ObjectSpace is a feature in Ruby that allows you to enumerate all objects of a given type in the current runtime. In the C implementation, this is easy to provide, since ObjectSpace is basically a thin wrapper around the memory manager. Under JRuby, however, where we can't enumerate objects managed by Java's memory model, we have to provide a separate structure that governs a collection of references to such objects. This results in substantial overhead per-object when run under JRuby, since we have to create two or three times as many objects as are needed to run simply to implement ObjectSpace.
JRuby can be told to run without ObjectSpace by specifying the -O flag:
jruby -O bin/gem install rake
Obviously any programs that depend on ObjectSpace will not run correctly with the -O flag, but this is generally limited to a few of Rails own development-time scripts and test/unit test runners.
There is also a property to disable ObjectSpace:
jruby -J-Djruby.objectspace.enabled=false
Enabling ObjectSpace Dynamically
As of JRuby trunk r6137 a programs that knows it needs full ObjectSpace support can dynamically turn ObjectSpace on and off themselves This enables jirb to turn on ObjectSpace to have fully-functional code-completion (See JRUBY-2186).
require 'jruby' JRuby.objectspace=true
Enabling Thread Pooling
Ruby scripts frequently take advantage of the C impl's lightweight (green) threading by spinning up hundreds or thousands of threads during a run. Under JRuby, this can often mean that hundreds or thousands of native threads are spun up and thrown away, which is inefficient in many cases and on many platforms. As an alternative to straight-up 1:1 threading in JRuby, you may also enable thread pooling. When pooling is enabled, JRuby starts up only as many threads as are needed for concurrent tasks. Repeatedly launching short-lived Ruby threads then will reuse native threads. This can improve performance in many cases, especially when libraries like /timeout/ are employed that spin up a thread-per-call.
To enable pooling, set the Java system property "jruby.thread.pooling" to true:
jruby -J-Djruby.thread.pooling=true myscript.rb
Using JVM Parameters
Using the Java "server" VM
JRuby benefits greatly from running under the Java "server" VM, which trades startup, early-run performance for a much higher level of long-term optimization. JRuby will use the server VM of whatever Java version you are running if you specify pass the "-server" flag to the underlying JVM as follows:
jruby -J-server myscript.rb
Combining the server VM with the compiler and disabled ObjectSpace generally results in the fastest performance.
Setting the maximum heap space available for JRuby
jruby -J-Xmx512m
Setting the initial heap space available for JRuby
jruby -J-Xms512m
Setting the heap space for Young/Eden Garbage Collection
jruby -J-Xmn128m
All together now
First a few suggestions, set the minimum -Xms and maximum -Xmx heap sizes to the same value and the -Xmn value should be lower than the -Xmx value.
jruby -J-Xmn512m -J-Xms2048m -J-Xmx2048m -J-server
JRuby's runtime properties
jruby --properties These properties can be used to alter runtime behavior for perf or compatibility. Specify them by passing -J-D<property>=<value>
COMPILER SETTINGS:
jruby.compile.mode=JIT|FORCE|OFF
Set compilation mode. JIT is default; FORCE compiles all, OFF disables
jruby.compile.fastest=true|false
(EXPERIMENTAL) Turn on all experimental compiler optimizations
jruby.compile.boxed=true|false
(EXPERIMENTAL) Use boxed variables; this can speed up some methods. Default is false
jruby.compile.frameless=true|false
(EXPERIMENTAL) Turn on frameless compilation where possible
jruby.compile.positionless=true|false
(EXPERIMENTAL) Turn on compilation that avoids updating Ruby position info. Default is false
jruby.compile.threadless=true|false
(EXPERIMENTAL) Turn on compilation without polling for "unsafe" thread events. Default is false
jruby.compile.fastops=true|false
(EXPERIMENTAL) Turn on fast operators for Fixnum. Default is false
JIT SETTINGS:
jruby.jit.threshold=<invocation count>
Set the JIT threshold to the specified method invocation count. Default is 20
jruby.jit.max=<method count>
Set the max count of active methods eligible for JIT-compilation.
Default is 2048 per runtime. A value of 0 disables JIT, -1 disables max.
jruby.jit.logging=true|false
Enable JIT logging (reports successful compilation). Default is false
jruby.jit.logging.verbose=true|false
Enable verbose JIT logging (reports failed compilation). Default is false
jruby.jit.logEvery=<method count>
Log a message every n methods JIT compiled. Default is 0 (off).
NATIVE SUPPORT:
jruby.native.enabled=true|false
Enable/disable native extensions (like JNA for non-Java APIs; Default is true
(This affects all JRuby instances in a given JVM)
jruby.native.verbose=true|false
Enable verbose logging of native extension loading. Default is false.
jruby.fork.enabled=true|false
(EXPERIMENTAL, maybe dangerous) Enable fork(2) on platforms that support it.
THREAD POOLING:
jruby.thread.pool.enabled=true|false
Enable reuse of native backing threads via a thread pool. Default is false.
jruby.thread.pool.min=<min thread count>
The minimum number of threads to keep alive in the pool. Default is 0.
jruby.thread.pool.max=<max thread count>
The maximum number of threads to allow in the pool. Default is unlimited.
jruby.thread.pool.ttl=<time to live, in seconds>
The maximum number of seconds to keep alive an idle thread. Default is 60.
MISCELLANY:
jruby.compat.version=RUBY1_8|RUBY1_9
Specify the major Ruby version to be compatible with; Default is RUBY1_8
jruby.indexed.methods=true|false
Generate "invokers" for core classes using a single indexed class
jruby.objectspace.enabled=true|false
Enable or disable ObjectSpace.each_object (default is disabled)
jruby.launch.inproc=true|false
Set in-process launching of e.g. system('ruby ...'). Default is true

