• Ruby implementation fi rst, JVM language second • Many bene fi ts from JVM ecosystem • Ruby code should "just work" • Different extension API, no forking, parallel threads • Thousands of production users, 18 years of real-world use
Language and core specs: 98% passing • Pure-Ruby standard library shared with CRuby • JRuby support for most native stdlib • JRuby 9.4 supports Ruby 3.1 • Maintained until April 2026
thousands of libraries • Graphics, GUIs, servers, document formats, AI/LLM • One of the largest collections in the dev world • All available to JRuby users! • Easy integration into Ruby apps and code
Like Bundler's Gem fi le • List of libraries and versions from Maven • lock_jars command • Like bundle install jar 'org.jfree:jfreechart:1.5.5' jar 'org.jfree:org.jfree.chart3d:2.1.0' $ lock_jars -- jar root dependencies -- org.jfree:jfreechart:1.5.5:compile org.jfree:org.jfree.chart3d:2.1.0:compile org.jfree:org.jfree.svg:5.0.6:compile org.jfree:org.jfree.pdf:2.0:compile Jars.lock updated
...) • JRuby + SWT is the most mature • JRuby makes cross-platform GUI much easier! • Works same everywhere • GUI libraries shipped with gem • https://github.com/AndyObtiva/glimmer
Heap size: small or large? • Throughput: faster allocations or shorter pause times? • Working set: large in-memory or mostly new objects? • Many options in standard OpenJDK • Serial, Parallel, G1, ZGC, Shenandoah
C1 "client" JIT: fast, simple optimizations • C2 "server" JIT: needs pro fi le data, heavy optimization • Both enabled with various "tiers" of JIT • Graal JIT: newer, more aggressive optimizations • OpenJ9 JIT (IBM JDK): of fl ine AOT, JIT servers, CRIU
basic JVM monitoring • JDK Flight Recorder: always-on monitoring with pro fi ling options • Low-overhead 1% to 5%, built into OpenJDK • JDK Mission Control: GUI client for Flight Recorder data • https://adoptium.net/jmc/
threads, so we need worker processes • Processes duplicate runtime state and waste resources • JRuby is a good solution • Multi-threaded single process runs your entire site • Single process with leading-edge GC uses resources better
always had much longer startup than CRuby • JVM must load, parse, optimize each time • Delaying parts of startup only helps "hello world" • Newer JDKs shipping improved startup features
Pre-cache classes, methods, code, metadata across runs • Machine code caching (AOTCache) • AppCDS + execution pro fi les and native code • Coordinated restore at checkpoint (CRaC) • Capture entire process state and restore later (repeatedly)
• JVM has world-class JIT compilers, garbage collectors • Similar design to ZJIT, but with 30 years of work in it • JRuby itself has an IR, basic block-based interpreter and JIT • Similar design to ZJIT starting in JRuby 9.0 (2015)
• Only abstraction was a native thread, too heavy for 1000s of fi bers • OpenJDK Project Loom adds fi bers to JVM • "Virtual threads" are lightweight, but use same thread API • JRuby can match CRuby for count and perf of fi bers
Using C code to allocate + initialize hurts performance • JRuby implemented this in 2016 • If Class#new is default, allocate and call #initialize inline • Allocation and initialize both inline back to caller
to Ruby • You must write Ractor-friendly code • High overhead crossing Ractor boundary • Threads in JRuby are already 100% concurrent • You must right Thread-friendly code • But zero overhead due to shared object • Thanks to Maciej Mensfeld for the benchmark
users with JRuby • Keep making JRuby better • Sponsorships from users • Every little bit helps! • JRuby and Ruby support • Migration, updates, performance work
we are 3.4 compatible, I can work on fun stuff • If you fi nd something slower than CRuby, tell me! • More JDK features • AOTCache for startup, Panama for fast native calls • Upgrade JVM, your JRuby code runs faster!