Open headius opened 1 year ago
Running on 22.3 GraalVM CE on MacOS 13 on M1.
Thank you for the report. I wonder if this is architecture-specific or so, we'll check.
Happens as well on x86_64 Linux.
Does it work if you increase it like the message suggests? It should be something like --vm.XX:NonProfiledCodeHeapSize=512m
, in TRUFFLERUBYOPT or RUBYOPT or as a command line argument.
I can't double-check myself right now.
Could you share the siege command line and which database & gem is used? Even better would be a repository I can just use to reproduce.
I cannot reproduce it with the instructions in the description on truffleruby 22.3.1, like ruby 3.0.3, GraalVM EE Native [x86_64-linux]
(JDK 17) and guessing the rest.
I did:
siege -c1 -t5s http://127.0.0.1:3000/posts
, that gives ~633rpsgem install bundler
to get latest Bundler (the one shipped with it is too old)ruby "3.2.1"
from the Gemfilebundle install
RAILS_ENV=production RUBYOPT='--jvm --experimental-options --cexts-lock=false' bundle exec rails s
siege -c1 -t5s http://127.0.0.1:3000/posts
, after warmup that gives ~894rps, but with a fair bit of variance between each run of 5 seconds.I don't see any warning about CodeHeap.
I downloaded EE via:
bash <(curl -sL https://get.graalvm.org/ee-token)
bash <(curl -sL https://get.graalvm.org/jdk)
as documented on https://www.graalvm.org/downloads/
There are several problems with this repro though:
.css
files, even on CRuby: ActionController::RoutingError (No route matches [GET] "/assets/es-module-shims.min-d89e73202ec09dede55fb74115af9c5f9f2bb965433de1c2446e1faa6dac2470.js"):
.This would all be addressed by sharing a github repository, and e.g. a script containing the siege command line.
I will push a repository later but also I will update the instructions in the other bug.
The other bug is closed so I added instructions for building the app here. It is a standard scaffolded blog post app with one post, running 16-way on default sqlite configuration.
Thank you for the more detailed repro instructions, I can now reproduce it.
It needs quite a few siege
runs, and letting it compile for a while without hitting it with siege made it happen for me.
Unfortunately we are very close to RubyKaigi so I don't think I will have time to investigate much further before the conference.
Maybe there is a deoptimization loop in 22.3 that causes the high usage of JITed code (notably there seems to be many repeated compilations of Truffle::Splitter
methods).
That's possibly fixed on master, I will try to check.
Setting only NonProfiledCodeHeapSize alone does not work, as I guess you saw:
$ export RUBYOPT='--jvm --experimental-options --cexts-lock=false --vm.XX:NonProfiledCodeHeapSize=512m'
$ RAILS_ENV=production RAILS_MAX_THREADS=16 rails s
Error occurred during initialization of VM
Invalid code heap sizes: NonNMethodCodeHeapSize (4K) + ProfiledCodeHeapSize (4K) + NonProfiledCodeHeapSize (524288K) = 524296K is greater than ReservedCodeCacheSize (327680K).
But setting ReservedCodeCacheSize as well does work:
$ export RUBYOPT='--jvm --experimental-options --cexts-lock=false --vm.XX:NonProfiledCodeHeapSize=512m --vm.XX:ReservedCodeCacheSize=1g'
Obviously this is not tuned for the best memory usage, that would need a proper Xmx and finding a good value for NonProfiledCodeHeapSize.
For benchmarking, use TruffleRuby --jvm EE, as mentioned on https://github.com/oracle/truffleruby/blob/master/doc/user/benchmarking.md#use-truffleruby-ee. CE is not representative of TruffleRuby's best performance (a bit like JRuby without invokedynamic).
From the output with --engine.TraceCompilation
, the many repeated compilations of Truffle::Splitter
methods seems the problem, which sounds like a deoptimization loop.
That could explain the high amount of generated code, memory usage, and likely also lower performance, as it means some part often runs in the interpreter.
To give an idea, on 22.3.1 CE I see ~4500 RPS and on master EE I see ~7850 RPS, on a linux-amd64 machine with 18 physical cores.
That run on master EE didn't run into that deoptimization loop issue, but it would need more runs to be confident it's solved as it seems to not always happen. There is also current work in the compiler to avoid problems with deoptimization loops.
Set-up instructions below, with 16-way concurrency/DB on server and siege hitting it with 16 threads. I could not find a way to set this flag. This is TruffleRuby 22.3 JVM CE.
Set-up of application
Generate app:
Configure database appropriately for chosen target. I used standard sqlite configuration to reproduce the issue.
Populate the database and start the application.