Slide 1

Slide 1 text

Looking Forward!

Slide 2

Slide 2 text

Who Am I • Charles Oliver Nutter • @headius(@mastodon.social) • headius@headius.com • JRuby developer since 2004 • Full-time JRuby and JVM language advocate since 2006

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

What is JRuby? • Ruby atop the Java Virtual Machine • 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, 15+ years of real-world use

Slide 6

Slide 6 text

What Is Important? • Usability: compatibility, startup time, warmup time • Runtime features: GC, JIT, monitoring, pro fi ling, concurrency • Platform features: mobile, server, desktop, integration, deployment • Performance: straight line, scaling, parallelism, resource usage • Different applications needs different capabilities

Slide 7

Slide 7 text

Getting Started

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

JRuby Install • Install a JDK • Java 11+ recommended, there's many distributions out there • Java 8 supported for 9.4 and lower • Install JRuby • Recommended: Ruby installer, system package, Docker image • Download tarball/zip or Windows installer

Slide 10

Slide 10 text

Test it out! [] ~ $ rvm use jruby Using /Users/headius/.rvm/gems/jruby-9.4.2.0 [] ~ $ irb >> runtime = java.lang.Runtime.runtime => # >> runtime.available_processors => 8 >> runtime.free_memory => 91420584 >>

Slide 11

Slide 11 text

Usability

Slide 12

Slide 12 text

Ruby Compatibility • JRuby 9.4 is Ruby 3.1 compatible • 98% of language specs passing • Nearly complete core + stdlib features from 2.7, 3.0 and 3.1 • JRuby 9.3 (Ruby 2.6 compat) maintaned through 2023 • JRuby 9.5 with 3.2 support before 2024 (help us!) • Compatibility before performance!

Slide 13

Slide 13 text

Very high language compatibility High core compatibility, missing parts mostly POSIX things Most of stdlib works well, MRI-speci fi c extensions excluded Nearly all command line works same https://eregon.me/rubyspec-stats/

Slide 14

Slide 14 text

Startup Time • JVM is not designed to start up quickly • Most of core JDK starts in interpreter • Long tail to optimize code and reach peak performance • JRuby makes it worse • Ruby parser, compiler and interpreter are interpreted by JVM • Lazy compile to bytecode, bytecode is interpreted by JVM

Slide 15

Slide 15 text

JRuby Architecture Ruby (.rb) JIT Java Instructions (java bytecode) Ruby Instructions (IR) parse interpret interpreter interpret C1 compile native code better native code java bytecode interpreter execute C2 compile Java Virtual Machine JRuby Internals

Slide 16

Slide 16 text

ruby -e 1 0s 0.45s 0.9s 1.35s 1.8s -e 1 1.686s 0.053s CRuby 3.2 JRuby 9.4

Slide 17

Slide 17 text

JRuby With Full Optimization Ruby (.rb) JIT Java Instructions (java bytecode) Ruby Instructions (IR) parse interpret interpreter interpret better native code java bytecode interpreter C1 compile native code execute C2 compile Java Virtual Machine JRuby Internals

Slide 18

Slide 18 text

JRuby --dev Mode Ruby (.rb) Ruby Instructions (IR) parse interpret interpreter Java Virtual Machine JRuby Internals C1 compile interpreter as native code execute

Slide 19

Slide 19 text

ruby -e 1 0s 0.45s 0.9s 1.35s 1.8s -e 1 1.271s 1.686s 0.053s CRuby 3.2 JRuby 9.4 JRuby 9.4 --dev

Slide 20

Slide 20 text

rails new testapp --skip-bundle 0s 1.5s 3s 4.5s 6s rails new testapp --skip-bundle 2.7s 5.918s 0.314s CRuby JRuby JRuby --dev

Slide 21

Slide 21 text

Ahead-of-time Compilation • Maybe we can start with native code? • GraalVM Native Image is a well known option • Disables most dynamic JVM features • Project Leyden: standardized AOT for Hotspot JVM • Start native, but support and optimize dynamic stuff later!

Slide 22

Slide 22 text

ruby -e 1 0s 0.75s 1.5s 2.25s 3s -e 1 0.034s 2.308s 1.271s 1.686s 0.053s CRuby 3.2 JRuby 9.4 JRuby 9.4 --dev Tru ffl eRuby --jvm Tru ffl eRuby native

Slide 23

Slide 23 text

rails new testapp --skip-bundle 0s 4s 8s 12s 16s rails new testapp --skip-bundle 3.218s 15.676s 2.7s 5.918s 0.314s CRuby JRuby JRuby --dev Tru ffl eRuby --jvm Tru ffl eRuby native

Slide 24

Slide 24 text

Snapshot a "Warm" JRuby? • Pre-optimize and save a snapshot? • CRIU: Checkpoint and Restore in Userspace (Linux only) • IBM Semeru JDK "InstantOn" • Working prototype with JRuby! • CRaC: OpenJDK support for checkpoint and restore • Cross-platform and standardized (coming soon?)

Slide 25

Slide 25 text

ruby -e 1 0s 0.45s 0.9s 1.35s 1.8s -e 1 0.21s 1.271s 1.686s 0.053s CRuby 3.2 JRuby 9.4 JRuby 9.4 --dev JRuby 9.4 CRIU

Slide 26

Slide 26 text

rails new testapp --skip-bundle 0s 1.5s 3s 4.5s 6s rails new testapp --skip-bundle 0.89s 2.7s 5.918s 0.314s CRuby JRuby JRuby --dev JRuby CRIU

Slide 27

Slide 27 text

Runtime Features

Slide 28

Slide 28 text

JVM GC • Many options to tune JVM GCs • 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, MMtk

Slide 29

Slide 29 text

Visual VM

Slide 30

Slide 30 text

JVM JIT • HotSpot JIT is most widely deployed • 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

Slide 31

Slide 31 text

Monitoring and Pro fi ling • VisualVM: GUI console for 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/

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Project Loom • JRuby's fi bers are based on threads • Too many, JVM blows up! • Scheduling, resource-intensive • Loom brings fi bers to JVM • Easily handles thousands of fi bers • Faster context-switching

Slide 37

Slide 37 text

5.times do t = Time.now # create 100k fibers ary = 100_000.times.map { Fiber.new { } } # resume and complete 100k fibers ary.each(&:resume) p Time.now - t end

Slide 38

Slide 38 text

$ jruby fiber_test.rb [7.603s][warning][os,thread] Attempt to protect stack guard pages failed (0x00007fc240a00000-0x00007fc240a04000). # # A fatal error has been detected by the Java Runtime Environment: # Native memory allocation (mprotect) failed to protect 16384 bytes for # memory to guard stack pages # # An error report file with more information is saved as: # /home/headius/work/jruby93/hs_err_pid75149.log # # If you would like to submit a bug report, please visit: # https://bugreport.java.com/bugreport/crash.jsp # Aborted (core dumped) 😩

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

$ jruby -J--enable-preview fiber_test.rb 2.324123 0.880373 0.6916289999999999 0.73703 0.655856 🤩

Slide 42

Slide 42 text

C100k on JRuby? • See @ioquatix talks on async and falcon! • Just starting to add support for io-event, async-io in JRuby • To do: Fiber/IO scheduler and Buffer APIs • Great way to contribute!

Slide 43

Slide 43 text

Project Panama: FFI for JVM • Foreign function interface (FFI) • With JVM help to make direct calls • Foreign memory API • JVM-assisted access, lifecycle • API extraction from C/++ headers • Save time setting up bindings

Slide 44

Slide 44 text

jextract code generator • Writing bindings using FFI or Fiddle is still challenging • Parameter sizes, struct layout, in and out values, pointers • Differences across platforms • jextract: produce Panama/FFI stub code from a C header fi le • Call that stub code from JRuby... easy FFI for all! //point.h struct Point2d { double x; double y; }; double distance(struct Point2d); jextract --source -t org.jextract point.h import java.lang.foreign.*; import static org.jextract.point_h.*; import org.jextract.Point2d; var session = MemorySession.openCon fi ned(); MemorySegment point = MemorySegment.allocateNative(Point2d.$LAYOUT(), session); Point2d.x$set(point, 3d); Point2d.y$set(point, 4d); distance(point);

Slide 45

Slide 45 text

SQLite JDBC Adapter • Java DataBase Connectivity (JDBC) wrapper around SQLite • Used by JRuby for ActiveRecord, Sequel • Java Native Interface (JNI) currently, limits throughput • Proof-of concept Panama-based version working now • 2x performance for most operations

Slide 46

Slide 46 text

Yet Another Ruby Parser (YARP) • Simple C library for parsing Ruby that we can share • JRuby already integrating it! • 60% of nodes implemented, 
 `gem list` almost runs! • 20% faster startup for "-e 1" • Using JNI, but could be even faster with Panama

Slide 47

Slide 47 text

GUIs, Graphics, and Games

Slide 48

Slide 48 text

GUI Libraries • Swing, built into JDK • Clean, cross-platform, easy to build simple UIs • Scalable Windowing Toolkit (Eclipse SWT) • Native widgets, WebKit browser component, rich ecosystem • JavaFX (via JRubyFX, github/jruby/jrubyfx) • Scene-based, vector drawing, event-driven modern UI library

Slide 49

Slide 49 text

Shoes 4

Slide 50

Slide 50 text

Glimmer • Glimmer GUI DSL • Multiple backends (SWT, GTK, ...) • JRuby + SWT is the most mature • JRuby makes cross-platform GUI much easier! • Works same everywhere • GUI libraries shipped with gem

Slide 51

Slide 51 text

JRubyFX • JRuby wrapper for JavaFX • Supports FXML layout or direct widget scripting • Could be combined with Ruboto for FX on Android apps!

Slide 52

Slide 52 text

GUIs... like Android?

Slide 53

Slide 53 text

Ruboto: JRuby on Android • ruboto.org, 
 https://github.com/ruboto/ruboto • Actively used for commercial projects today • Build interface with GUI builder, wire it up with Ruby code • Neglected a bit but being updated for JRuby 9.4 now!

Slide 54

Slide 54 text

Ruboto IRB • IRB in JRuby on Android! • Plus an editor and script runner • Not currently in the store, but we will republish soon! • Search for "Ruboto Core" and "Ruboto IRB" APKs

Slide 55

Slide 55 text

Updated Ruboto! • We are updating Ruboto! • JRuby 9.4, with Ruby 3.1 support • Latest versions of Android • Still a few bugs to work through • https://github.com/ruboto/JRuby9k_POC • jruby_9_4 branch • bundle install ; rake assemble

Slide 56

Slide 56 text

Performance and Scaling

Slide 57

Slide 57 text

Scaling Applications • Classic problem on CRuby/MRI • No concurrent 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

Slide 58

Slide 58 text

Baseline Rails App • Scaffolded "blog" application on PostgreSQL, Puma • IBM VPC instance: 8 vCPU, 32GB • CRuby 3.2, 16 workers • JRuby 9.4: 16 threads • Database, siege benchmark driver on same instance

Slide 59

Slide 59 text

Requests per second 0 450 900 1350 1800 60s siege iteration 1 2 3 4 5 6 7 JRuby CRuby 3.2 CRuby 3.2 + YJIT

Slide 60

Slide 60 text

requests per second (higher is better) 0rps 450rps 900rps 1350rps 1800rps 1,550rps 1,280rps 1,705rps JRuby 9.4 CRuby 3.2 CRuby + YJIT

Slide 61

Slide 61 text

Memory • JRuby: 3.4GB RSS • JRuby with 300MB heap: 955MB RSS • JRuby G1: 1.6G • CRuby: 16x 103MB = 1.6GB • CRuby YJIT: 16x 125MB = 2GB

Slide 62

Slide 62 text

requests per second (higher is better) 0rps 450rps 900rps 1350rps 1800rps 1,643rps 1,550rps 1,280rps 1,705rps JRuby 9.4 CRuby 3.2 CRuby + YJIT JRuby 300MB heap

Slide 63

Slide 63 text

RPS per MB of memory (16-way concurrency) 0rps/mb 0.45rps/mb 0.9rps/mb 1.35rps/mb 1.8rps/mb 1.72 rps/MB 0.775 rps/MB 0.8 rps/MB 0.501 rps/MB JRuby 9.4 CRuby 3.2 CRuby + YJIT JRuby 300MB heap

Slide 64

Slide 64 text

RPS per MB of memory (160-way concurrency) 0rps 3.5rps 7rps 10.5rps 14rps 13.692 rps/MB 0.775 rps/MB 0.8 rps/MB 4.871 rps/MB JRuby 9.4 CRuby 3.2 CRuby + YJIT JRuby 300MB heap ¥¥¥¥

Slide 65

Slide 65 text

JRuby Future • JRuby 9.4 continues to stabilize • Big optimization work coming the rest of this year • JRuby 9.5: Java 17, Ruby 3.2, many optimizations • Lots of new JVM features to leverage • Very exciting time for Rubyists! • Try JRuby today and let us know how it goes!

Slide 66

Slide 66 text

Thank You! • Charles Oliver Nutter • headius@headius.com • @headius(@mastodon.social) • https://github.com/jruby/jruby • https://www.jruby.org