Skip to content

Fix memory leak and upgrade to JRuby 9.4.15.0#81

Merged
corporate-gadfly merged 5 commits into
OpenVoxProject:mainfrom
Sharpie:upgrade-9415
Jul 6, 2026
Merged

Fix memory leak and upgrade to JRuby 9.4.15.0#81
corporate-gadfly merged 5 commits into
OpenVoxProject:mainfrom
Sharpie:upgrade-9415

Conversation

@Sharpie

@Sharpie Sharpie commented Jul 6, 2026

Copy link
Copy Markdown
Member

Short description

This changeset adds a test for the memory leak reported in #76, then a fix for the leak, and finally an upgrade to the 9.4.15.0 release of JRuby. JRuby 9.4.x is now end-of-life, these changes get us caught up on fixes and lay the groundwork for moving to JRuby 10.

Checklist

I have:

Sharpie and others added 5 commits July 6, 2026 12:24
Signed-off-by: Charlie Sharpsteen <charlie@overlookinfratech.com>
Over the history of JRuby use in the server, there have been several
incidents where a JRuby instance survives the shutdown of the JRuby pool
service. This is one of the most severe memory leaks possible for the
Server as it results in at least several hundred megabytes leaked for
the Runtime, and then an indeterminate amount of additional leaked RAM
for module content and user data.

This commit adds an integration test that spins up a JRuby pool,
exercises it with some Ruby code, and then shuts it down. After
shutdown, `java.lang.System.gc()` is called and the test asserts that
the JRuby instances are destroyed by the garbage collector.

The lifecycle of this test case is unusual in that it runs everything
on a separate thread pool that is also shut down at the end of the
test. This is done because any Java Thread that calls into a JRuby
instance to execute Ruby code gains a soft reference to that JRuby.
Soft references are not released by regular `System.gc()`, the JVM has
to be put under actual memory pressure before it panics and destroys
them --- and forcing an `OutOfMemory` error in the test case and then
rescuing it is a bit too spicy.

This test will not detect all usage patterns that lead to a JRuby
leaking. Currently, it targets an issue introduced in the 9.4.13.0
release of JRuby that results in proxy objects, created when Ruby
code calls into Java, holding onto strong references to the JRuby
instance.

If additional usage patterns lead to occurring, they can be added
as new cases on this test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Charlie Sharpsteen <charlie@overlookinfratech.com>
The JRuby 9.4.13.0 release re-factored storage of proxy objects that get
created when Ruby code interacts with Java classes. Prior versions of
JRuby stored these proxies in a hashmap owned by the JRuby interpreter
that has the unfortunate behavior of growing without bound if the number
of unique Java interactions is not limited. JRuby 9.4.13.0 introduced
a new `STABLE` accounting method the attempts to address this by using
weak references to the proxies attached to the Java classes themselves.

Unfortunately, there was a strong reference mixed in that is not cleared
when a JRuby instance shuts down and that makes shut-down JRubies
unavailable for garbage collection. This causes the OpenVox Server tests
to throw `OutOfMemoryError` when JRuby is upgraded past 9.4.12.1 as the
tests spin up and then shut down several JRuby pools.

This commit fixes the glitch by pinning the `ji.class.values` setting
to the old `HARD_MAP` default. The leak is fixed by upstream PR
jruby/jruby#9359 which was released with JRuby 10.0.5.0. The new default
of `STABLE` should be usable starting with that version.

Fixes OpenVoxProject#76

Signed-off-by: Charlie Sharpsteen <charlie@overlookinfratech.com>
This upgrade is possible now that the memory leak described in
OpenVoxProject#76 is fixed.

Signed-off-by: Charlie Sharpsteen <charlie@overlookinfratech.com>
The logic for initializing JRuby instances sets `jruby.invokedynamic.yield`
to `false` instead of the default value of `true`. This was done to resolve
a stack overflow that is described in jruby/jruby#6260. That issue was
fixed upstream with the release of JRuby 9.2.15.0.

Making a large change to optimizer behavior is a bit much for a stable
release, so this commit adds a `FIXME` note to drop the override when
taking up JRuby 10.

Signed-off-by: Charlie Sharpsteen <charlie@overlookinfratech.com>
@corporate-gadfly corporate-gadfly merged commit 7b059ed into OpenVoxProject:main Jul 6, 2026
6 checks passed
@Sharpie Sharpie changed the title Upgrade 9415 Fix memory leak and upgrade to JRuby 9.4.15.0 Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants