<div dir="ltr"><div>Hello! I have been playing with running JRuby on the latest builds of Azul ZuluĀ + CRaC and I am very impressed!</div><div><br></div><div>Baseline "hello world" startup of JRuby improves by 15-20x, which says as much about our fat boot cycle as it does about CRaC's outstanding restore performance.</div><div><br></div><div>```</div><div>~/work/jruby $ jruby --checkpoint<br>Sep 05, 2024 4:16:39 AM jdk.internal.crac.LoggerContainer info<br>INFO: Starting checkpoint<br>Sep 05, 2024 4:16:39 AM jdk.internal.crac.LoggerContainer info<br>INFO: /home/headius/work/jruby/lib/jruby.jar is recorded as always available on restore<br>CR: Checkpoint ...<br>Killed<br><br>~/work/jruby $ time jruby --restore -e "puts 'hello'"<br>hello<br><br>real   0m0.110s<br>user  0m0.111s<br>sys   0m0.049s<br><br>~/work/jruby $ time jruby -e "puts 'hello'"<br>hello<br><br>real        0m1.827s<br>user  0m5.377s<br>sys   0m0.183s<br></div><div>```</div><div><br></div><div>I was also impressed how quickly my two previous bugs were fixed after I reported them to Anton Kozlov (command line argument quoting issues and really slow compressed image restoration).</div><div><br></div><div>I have two weird ideas for using CRaC plus a possible bug to report.</div><div><br></div><div>* Idea #1: CRaC checkpointing as a really slow JVM fork(2).</div><div><br></div><div>JRuby has never been able to support forking the JVM because of challenges restoring the new process to full functionality: restarting GC and JIT threads, managing signals and file descriptors, etc. CRaC is already doing that in order to restore from a checkpoint!</div><div><br></div><div>What if I wanted the checkpoint process to keep executing, but start up a child process by restoring the checkpoint I just acquired? Presto, super-slow forking!</div><div><br></div><div>Am I crazy?</div><div><br></div><div>* Idea #2: Incremental checkpointing</div><div><br></div><div>I don't know if there's any technical limitation on acquiring a new checkpoint after restoring from an old checkpoint, but there's one practical limitation: you can't change the target directory for the new checkpoint.</div><div><br></div><div>I would like to be able to incrementally improve a checkpoint, dumping the image to a new directory of my choosing each time. This would allow a checkpoint/restore chain similar to re-forking servers, which base later forks on the warmed-up children of previous forks. I could provide a baseline JRuby image that users could customize to their specific applications and load patterns.</div><div><br></div><div>It would seem a checkpointRestore(Path) should be doable, yes?</div><div><br></div><div>* Possible bug: overwriting a compressed checkpoint with an uncompressed checkpoint produces a non-bootable image.</div><div><br></div><div>I ran into this while investigating checkpoint compression speed recently, and Anton suggested I post it here.</div><div><br></div><div>```</div><div>~/work/jruby $ rm -rf .jruby.checkpoint/<br><br>~/work/jruby $ jruby --checkpoint -J-XX:+CRaCImageCompression<br>Sep 05, 2024 4:14:54 AM jdk.internal.crac.LoggerContainer info<br>INFO: Starting checkpoint<br>Sep 05, 2024 4:14:54 AM jdk.internal.crac.LoggerContainer info<br>INFO: /home/headius/work/jruby/lib/jruby.jar is recorded as always available on restore<br>CR: Checkpoint ...<br>Killed<br><br>~/work/jruby $ jruby --restore -e "puts 'hello'"<br>hello<br><br>~/work/jruby $ jruby --checkpoint<br>Sep 05, 2024 4:15:25 AM jdk.internal.crac.LoggerContainer info<br>INFO: Starting checkpoint<br>Sep 05, 2024 4:15:25 AM jdk.internal.crac.LoggerContainer info<br>INFO: /home/headius/work/jruby/lib/jruby.jar is recorded as always available on restore<br>CR: Checkpoint ...<br>Killed<br><br>~/work/jruby $ jruby --restore -e "puts 'hello'"<br>pie: 398386: Error (criu/pie/util-vdso.c:92): vdso: ELF header magic mismatch<br>pie: 398386: Error (criu/pie/restorer.c:2194): Restorer fail 398386<br>Error (criu/cr-restore.c:2605): Restoring FAILED.<br></div><div>```</div><div><br></div><div>You should be able to reproduce this with a build of JRuby (<a href="https://github.com/jruby/jruby">https://github.com/jruby/jruby</a>) from the "crac" branch.</div><div><br></div><div>Thanks for your work!</div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><b>Charles Oliver Nutter</b><div><i>Architect and Technologist</i></div><div>Headius Enterprises</div><a href="https://www.headius.com" target="_blank">https://www.headius.com</a><div><div><a href="mailto:headius@headius.com" target="_blank">headius@headius.com</a></div></div></div></div></div></div>