Skip to content

Timeout::timeout leads to OOM with multiple threads #8406

@jsvd

Description

@jsvd

This is a follow up to #8403 where #8404 fixed the single threaded crash but we're observing an OOM when multiple threads are involved.
The OOM happened less frequently in our tests before #8404 since the TimeoutException "leak" would typically happen first.

Environment Information

jruby 9.4.9.0-SNAPSHOT (3.1.4) 2024-11-04 746b84a OpenJDK 64-Bit Server VM 21.0.2+13-LTS on 21.0.2+13-LTS +jit [arm64-darwin]

Expected Behavior

1 thread seems to work fine and we can see the 10 million iterations finishing after 55 seconds:

❯ time JRUBY_OPTS="-J-Xmx128m -Xreify.classes=true" bin/jruby -rtimeout -e "timeout = 0.001; 1.times.map { Thread.new { 10_000_000.times { Timeout::timeout(timeout) { } rescue nil; } } }.each(&:join)"
JRUBY_OPTS="-J-Xmx128m -Xreify.classes=true" bin/jruby -rtimeout -e   67.62s user 11.53s system 143% cpu 55.135 total

It'd be expected that multiple threads would also complete in a similar amount of time.

Actual Behavior

With 2 threads the process OOMs eventually:

/tmp/jruby-9.4.9.0-SNAPSHOT
❯ time JRUBY_OPTS="-J-Xmx128m -Xreify.classes=true" bin/jruby -rtimeout -e "timeout = 0.001; 2.times.map { Thread.new { 10_000_000.times { Timeout::timeout(timeout) { } rescue nil; } } }.each(&:join)"

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-1: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-2: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

JRUBY_OPTS="-J-Xmx128m -Xreify.classes=true" bin/jruby -rtimeout -e   332.54s user 26.38s system 137% cpu 4:20.93 total

same but much faster with 10 threads:

/tmp/jruby-9.4.9.0-SNAPSHOT
❯ time JRUBY_OPTS="-J-Xmx128m -Xreify.classes=true" bin/jruby -rtimeout -e "timeout = 0.001; 10.times.map { Thread.new { 10_000_000.times { Timeout::timeout(timeout) { } rescue nil; } } }.each(&:join)"

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-3: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-2: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-6: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-7: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-8: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-10: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-4: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-5: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-9: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Ruby-0-Thread-1: -e:1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

JRUBY_OPTS="-J-Xmx128m -Xreify.classes=true" bin/jruby -rtimeout -e   142.85s user 1.79s system 289% cpu 50.048 total

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions