Skip to content

Instantly share code, notes, and snippets.

View headius's full-sized avatar

Charles Oliver Nutter headius

View GitHub Profile
@headius
headius / gist:a824c87293ac8f96bfa65f8f838da7cd
Created October 22, 2025 20:33
Single-jar deployment of Sidekiq running the plain-old-Ruby example
sidekiq $ export RAILS_VERSION=7.1
sidekiq $ bundle
...
Bundle complete! 21 Gemfile dependencies, 88 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
sidekiq $ warble
rm -f sidekiq.jar
Creating sidekiq.jar
sidekiq $ export JDK_JAVA_OPTIONS=-Djava.net.preferIPv4Stack=true
sidekiq $ java -jar sidekiq.jar -r ./examples/por.rb
@headius
headius / console.txt
Created October 17, 2025 18:02
Two steps to create a redistributable Ruby app in an executable jar
[] image_voodoo_demo $ jruby -Ilib exe/voodoo PXL_20250802_162259596.jpg
wrote demo files to /Users/headius/work/image_voodoo_demo/PXL_20250802_162259596/
[] image_voodoo_demo $ ls PXL_20250802_162259596
border.jpg cropped_thumb.jpg cropped.jpg reduced.jpg resized.jpg resized.png thumb.jpg
[] image_voodoo_demo $ rm -rf PXL_20250802_162259596
[] image_voodoo_demo $ gem install warbler
Fetching warbler-2.1.0.gem
Successfully installed warbler-2.1.0
Parsing documentation for warbler-2.1.0
Installing ri documentation for warbler-2.1.0
@headius
headius / gist:88d91118ef1487b4fbff357fecf06904
Created October 2, 2025 17:07
JDK25 failing to load JRuby AppCDS JSA
] jdk25 $ rm /Users/headius/work/jruby/lib/jruby-java25.jsa
[] jdk25 $ /Library/Java/JavaVirtualMachines/zulu-25.jdk/Contents/Home/bin/java @/Users/headius/work/jruby/bin/.jruby.java_opts @/Users/headius/work/jruby/bin/.jruby.module_opts -Xss2048k -Djffi.boot.library.path=/Users/headius/work/jruby/lib/jni -Djava.security.egd=file:/dev/urandom -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=/Users/headius/work/jruby/lib/jruby-java25.jsa --enable-native-access=org.jruby.dist --sun-misc-unsafe-memory-access=allow --module-path /Users/headius/work/jruby/lib/jruby.jar -classpath : -Djruby.home=/Users/headius/work/jruby -Djruby.lib=/Users/headius/work/jruby/lib -Djruby.script=jruby -Djruby.shell=/bin/sh -Xlog:aot,cds org.jruby.Main -e 1
[0.007s][info][cds] Specified shared archive file not found (/Users/headius/work/jruby/lib/jruby-java25.jsa)
[0.012s][info][cds] trying to map /Library/Java/JavaVirtualMachines/zulu-25.jdk/Contents/Home/lib/server/classes.jsa
[0.012s][info][cds] Opened shared archive file /Librar
@headius
headius / training.md
Last active September 20, 2025 15:52
pre-trained JRuby + AOT for gem list

This is an experiment to pre-train and AOT enough of JRuby to get startup time for "gem list" down to a reasonable speed. I've tried various combintions and so far this seems to be the best, but the timings are highly variable.

Step 1: Perform a gem list while dumping IR. This saves the compiled IR for all loaded files to disk, to skip parsing and compiling in future runs.

jruby --dev -Xir.writing -S gem list > /dev/null

Step 2: Train AOT by running the following script repeatedly with the given JRuby arguments. Requires a small JRuby patch because IR reading breaks for any script has not been written (like the training script).

@headius
headius / gist:cf18f247c1a66f36210b50fcb10304f0
Created May 7, 2025 15:38
JRuby 10 start up and get NMT dump
Native Memory Tracking:
(Omitting categories weighting less than 1KB)
Total: reserved=1341322KB, committed=143578KB
malloc: 30682KB #118112, peak=33492KB #117863
mmap: reserved=1310640KB, committed=112896KB
- Java Heap (reserved=57344KB, committed=32768KB)
(mmap: reserved=57344KB, committed=32768KB, at peak)
@headius
headius / gist:911b66eac8d0cb8ef7b9f2ff8d9f4133
Created March 20, 2025 22:11
Crash loading shared archive on 23+valhalla build
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGBUS (0xa) at pc=0x0000000103e8e604, pid=4379, tid=35331
#
# JRE version: OpenJDK Runtime Environment (23.0+1) (build 23-valhalla+1-90)
# Java VM: OpenJDK 64-Bit Server VM (23-valhalla+1-90, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-aarch64)
# Problematic frame:
# V [libjvm.dylib+0x9ce604] SystemDictionaryShared::ArchiveInfo::lookup_lambda_proxy_class(LambdaProxyClassKey*)+0x5c
#
diff --git a/core/src/main/java/org/jruby/RubyBasicObject.java b/core/src/main/java/org/jruby/RubyBasicObject.java
index 4edab9b18a..985f2d1911 100644
--- a/core/src/main/java/org/jruby/RubyBasicObject.java
+++ b/core/src/main/java/org/jruby/RubyBasicObject.java
@@ -1791,8 +1791,8 @@ public class RubyBasicObject implements Cloneable, IRubyObject, Serializable, Co
* it possible to emulate both instance_eval and instance_exec
* with this implementation.
*/
- protected IRubyObject yieldUnder(final ThreadContext context, RubyModule under, IRubyObject[] args, Block block, EvalType evalType) {
- context.preExecuteUnder(this, under, block);

Comparing the run times for the most intensive job in our CI suite. JRuby 9.4 and 10 are both on Java 21 running equivalent settings. JRuby 10 can automatically utilize OpenJDK's AppCDS to improve startup time, and has many other optimizations for straight-line performance.

"Force JIT" here means JIT is enabled with a threshold of zero, causing nearly all methods and blocks to fully optimize and compile to JVM bytecode before running. JRuby 10 includes reductions in the overhead of the JIT and more are coming.

InvokeDynamic also can slow startup even as it improves execution performance. We have worked to reduce the overhead of InvokeDynamic use in JRuby while also utilizing it more effectively.

JRuby 9.4, force JIT, with full invokedynamic optimization.

Finished tests in 1053.596852s, 4.4125 tests/s, 1756.1271 assertions/s.
@headius
headius / aotcache.md
Last active February 13, 2025 14:38
Experimenting with JDK24 AOT caching and JRuby

Baseline startup

Base startup numbers with and without CDS (--nocache disables CDS), with and without --dev (simpler JVM JIT and no JRuby JIT)

[] jruby $ time jruby --nocache -e 1      
jruby --nocache -e 1  2.48s user 0.17s system 148% cpu 1.777 total
[] jruby $ time jruby --nocache -e 1
jruby --nocache -e 1  2.37s user 0.13s system 185% cpu 1.340 total
[] jruby $ time jruby --nocache -e 1
@headius
headius / macos on M1.md
Created January 11, 2025 09:01
JRuby startup tricks state of the art

JRuby without any flags

JRuby's startup without any flags is not unreasonable, but we're starting from a bad place.

jruby -e 1  2.57s user 0.17s system 166% cpu 1.648 total
[] jruby $ time jruby -e 1
jruby -e 1  2.46s user 0.13s system 183% cpu 1.407 total
[] jruby $ time jruby -e 1
jruby -e 1  2.48s user 0.13s system 179% cpu 1.455 total