truffleruby icon indicating copy to clipboard operation
truffleruby copied to clipboard

OutOfMemoryError on Rails app

Open djberg96 opened this issue 1 year ago • 2 comments

truffleruby 24.1.1, like ruby 3.2.4, Oracle GraalVM Native [x86_64-linux] Rails 7.1.x app

Just for kicks, tried deploying one of our smaller Rails apps to use truffleruby on a Ubuntu image.

$ RAILS_ENV=test bundle exec rspec spec/models/person_spec.rb

[ruby] WARNING OutOfMemoryError
[ruby] WARNING OutOfMemoryError

truffleruby: an internal exception escaped out of the interpreter,
please report it to https://github.com/oracle/truffleruby/issues

the lock was not held when calling unlockInternal() (com.oracle.truffle.api.CompilerDirectives.ShouldNotReachHere)
        from com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere(CompilerDirectives.java:603)
        from com.oracle.truffle.api.CompilerDirectives.shouldNotReachHere(CompilerDirectives.java:549)
        from org.truffleruby.core.mutex.MutexOperations.unlockInternal(MutexOperations.java:113)
        from org.truffleruby.cext.CExtNodes$CallWithCExtLockAndFrameAndUnwrapNode.callWithCExtLockAndFrame(CExtNodes.java:267)
        from org.truffleruby.cext.CExtNodesFactory$CallWithCExtLockAndFrameAndUnwrapNodeFactory$CallWithCExtLockAndFrameAndUnwrapNodeGen.execute(CExtNodesFactory.java:554)
        from org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:35)
        from org.truffleruby.core.module.ModuleNodes$DefineMethodNode$CallMethodWithLambdaBody.execute(ModuleNodes.java:1375)
        from org.truffleruby.language.RubyLambdaRootNode.execute(RubyLambdaRootNode.java:84)
/usr/local/lib/truffle/truffle/cext_ruby.rb:24:in '_native_parse'
        from /usr/local/bundle/gems/psych-5.1.2/lib/psych/parser.rb:62:in `parse'
        from /usr/local/bundle/gems/psych-5.1.2/lib/psych.rb:455:in `parse_stream'
        from /usr/local/bundle/gems/psych-5.1.2/lib/psych.rb:399:in `parse'
        from /usr/local/bundle/gems/psych-5.1.2/lib/psych.rb:272:in `unsafe_load'
        from /usr/local/bundle/gems/psych-5.1.2/lib/psych.rb:649:in `block in unsafe_load_file'
        from <internal:core> core/io.rb:576:in `open'
        from /usr/local/bundle/gems/psych-5.1.2/lib/psych.rb:648:in `unsafe_load_file'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/backend/base.rb:264:in `load_yml'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/backend/base.rb:243:in `load_file'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/backend/base.rb:17:in `block in load_translations'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/backend/base.rb:16:in `each'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/backend/base.rb:16:in `load_translations'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/backend/simple.rb:84:in `init_translations'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/backend/simple.rb:50:in `available_locales'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n/config.rb:45:in `available_locales'
        from /usr/local/bundle/gems/i18n-1.14.6/lib/i18n.rb:71:in `available_locales'
        from /usr/local/bundle/gems/faker-3.4.2/lib/faker.rb:25:in `locale'
        from /usr/local/bundle/gems/faker-3.4.2/lib/faker.rb:163:in `translate'
        from /usr/local/bundle/gems/faker-3.4.2/lib/faker.rb:109:in `fetch'
        from /usr/local/bundle/gems/faker-3.4.2/lib/faker.rb:133:in `parse'
        from /usr/local/bundle/gems/faker-3.4.2/lib/faker/default/name.rb:44:in `first_name'
        from /app/db/seeds.rb:35:in `block in <top (required)>'
        from <internal:core> core/integer.rb:155:in `times'
        from /app/db/seeds.rb:33:in `<top (required)>'
        from <internal:core> core/kernel.rb:386:in `load'
        from /usr/local/bundle/gems/railties-7.1.4.1/lib/rails/engine.rb:563:in `block in load_seed'
        from /usr/local/bundle/gems/activesupport-7.1.4.1/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
        from /usr/local/bundle/gems/activesupport-7.1.4.1/lib/active_support/execution_wrapper.rb:92:in `wrap'
        from /usr/local/bundle/gems/railties-7.1.4.1/lib/rails/engine.rb:649:in `block (2 levels) in <class:Engine>'
        from /usr/local/bundle/gems/activesupport-7.1.4.1/lib/active_support/callbacks.rb:130:in `instance_exec'
        from /usr/local/bundle/gems/activesupport-7.1.4.1/lib/active_support/callbacks.rb:130:in `block in run_callbacks'
        from /usr/local/bundle/gems/activesupport-7.1.4.1/lib/active_support/callbacks.rb:141:in `run_callbacks'
        from /usr/local/bundle/gems/railties-7.1.4.1/lib/rails/engine.rb:563:in `load_seed'
        from /app/spec/rails_helper.rb:29:in `block (2 levels) in <top (required)>'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/example.rb:457:in `instance_exec'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/example.rb:457:in `instance_exec'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/hooks.rb:365:in `run'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/configuration.rb:2186:in `block in run_suite_hooks'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/configuration.rb:2184:in `each'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/configuration.rb:2184:in `run_suite_hooks'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/configuration.rb:2091:in `with_suite_hooks'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/runner.rb:116:in `block in run_specs'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/reporter.rb:74:in `report'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/runner.rb:115:in `run_specs'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/runner.rb:89:in `run'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/runner.rb:71:in `run'
        from /usr/local/bundle/gems/rspec-core-3.13.1/lib/rspec/core/runner.rb:45:in `invoke'
        from /usr/local/bundle/gems/rspec-core-3.13.1/exe/rspec:4:in `<top (required)>'
        from <internal:core> core/kernel.rb:386:in `load'
        from /usr/local/bundle/bin/rspec:25:in `<top (required)>'
        from <internal:core> core/kernel.rb:386:in `load'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/cli/exec.rb:58:in `kernel_load'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/cli/exec.rb:23:in `run'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/cli.rb:455:in `exec'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/cli.rb:35:in `dispatch'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/cli.rb:29:in `start'
        from /usr/local/bundle/gems/bundler-2.5.17/exe/bundle:28:in `block in <top (required)>'
        from /usr/local/bundle/gems/bundler-2.5.17/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
        from /usr/local/bundle/gems/bundler-2.5.17/exe/bundle:20:in `<top (required)>'
        from <internal:core> core/kernel.rb:386:in `load'
        from /usr/local/bundle/bin/bundle:25:in `<main>'

#<Thread:0x5bd88 /usr/local/bundle/gems/activerecord-7.1.4.1/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb:42 run> terminated with exception (report_on_exception is true):
/usr/local/bundle/gems/activerecord-7.1.4.1/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb:42:in `block in spawn_thread': failed to allocate memory (NoMemoryError)

Line 33 of db_seeds.rb basically looks like this:

user = User.create(user_id: 12345)

20.times do
  person = {
    first_name: Faker::Name.first_name,
    middle_name: Faker::Name.middle_name,
    last_name: Faker::Name.last_name,
    # etc
  }

  CreateSomething.new(person, user.user_id).save

There's a bit of stuff going on inside CreateSomething.new but nothing too crazy. I can try to narrow it down if you need me to, but I thought I'd start with this and see if there are any known issues with psych, faker, etc.

djberg96 avatar Nov 19 '24 21:11 djberg96

Thank you for the report, we'll look into it.

andrykonchin avatar Nov 20 '24 10:11 andrykonchin

There are no known issues with psych, faker, etc. We would need a reproducer for this. Also, how much RAM do you have and how much is free/available?

The Oracle GraalVM Native standalone will use the G1 GC which means 25% of total RAM by default. You can increase it like e.g. export TRUFFLERUBYOPT=--vm.Xmx16g. You can check the max heap size in TruffleRuby with ruby -e 'pp GC.stat[:max]'.

eregon avatar Jan 09 '25 15:01 eregon