Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate static field references to JRuby state #5143

Closed
6 of 9 tasks
headius opened this issue Apr 17, 2018 · 4 comments
Closed
6 of 9 tasks

Eliminate static field references to JRuby state #5143

headius opened this issue Apr 17, 2018 · 4 comments
Milestone

Comments

@headius
Copy link
Member

headius commented Apr 17, 2018

We are doing an audit of JRuby and related projects looking for static references to JRuby state, since those references can anchor the JRuby instance, the classloader that loaded JRuby, and more.

I have fixed a number of cases for 9.1 in f248488. I fixed a few additional cases on master (9.2) in 95a41f9.

Here are my notes on other cases that did not have an easy fix...but they may not be problems.

  • Several static ThreadLocal in FFI, may anchor classloader that loaded those classes.
  • DataConverters.enumConverters is a static weak map of IRubyObject to converter, may work ok but uses our WeakIdentityHashMap, may anchor classloader. Keys may also interact weirdly across runtimes.
  • IR Profiler uses static collections for much of its data gathering.
  • Ruby < Java subclass creation uses static values during construction and possible in the generated class, with non-weak references to the runtime. Most during construction appear to be cleaned up (set back to original probably-null value).
  • Ruby implementing Java interfaces uses static fields for call sites. The generated class should be rootless, but this has been reported as a "leak" because the class holds on to too much data.
  • JarResource stores cache in a static field. Data should be weak, but this may need to be audited for leak potential.
  • (deprecate relevant code paths) BlockingIO caches selectors in a static CHM, mapping SelectorProvider to IOSelector. The latter will anchor SelectorProvider instances + classloader, and latter will anchor JRuby's classloader, but both are local (static global) to JRuby's classloader.
  • RubyEncoding has a ThreadLocal<SoftReference> which could anchor JRuby's classloader (for UTF8Coder) longer than would be ideal.
  • Embedding's SingletonLocalContextProvider holds a static reference to a runtime via localContext field. This may be by design.
@headius headius added this to the JRuby 9.2.0.0 milestone Apr 17, 2018
@enebo enebo modified the milestones: JRuby 9.2.0.0, JRuby 9.2.1.0 May 24, 2018
@headius headius modified the milestones: JRuby 9.2.1.0, JRuby 9.3.0.0 Oct 11, 2018
@headius
Copy link
Member Author

headius commented Oct 11, 2018

Reevaluate for 9.3.

@headius
Copy link
Member Author

headius commented Apr 6, 2021

Reviewing this in advance of 9.3 release.

Several static ThreadLocal in FFI, may anchor classloader that loaded those classes.

These all appear to be soft references. They will linger but should not leak in an unbounded way.

Several static ThreadLocal in FFI, may anchor classloader that loaded those classes.

This does not seem to be a problem. The map is weak-keyed, so should clear out after a runtime goes away, and uses identity to look up the value, which will isolate calls across runtimes.

Ruby < Java subclass creation uses static values during construction and possible in the generated class

Java subclasses are not intended to be usable across runtimes, and should be loading the generated class into our child JRubyClassLoader. @byteit101 may have comments here relating to #6422.

Ruby implementing Java interfaces uses static fields for call sites

I am not sure which issue is the "leak" mentioned here. Java interface implementations are, like Java subclasses, intended to be used only in the originating JRuby instance, and should be collected with that instance (and its JRubyClassLoader) is expunged.

JarResource stores cache in a static field

This is still the case, and I am still unsure if it is safe.

BlockingIO caches selectors in a static CHM, mapping SelectorProvider to IOSelector

SelectorProvider is loaded in the same classloader as this static CHM and the IOSelector instances should have no links to JRuby's runtime. This code is also deprecated and/or unused now (deprecate remaining references to this logic).

RubyEncoding has a ThreadLocal which could anchor JRuby's classloader

This is no more or less worrisome than other soft referenced threadlocals to JRuby-specific classes. We will deal with leak reports in the future (have had none about this or the other soft threadlocals above).

Embedding's SingletonLocalContextProvider holds a static reference to a runtime via localContext field. This may be by design.

This is by design. We may want to consider phasing this model out.

@headius
Copy link
Member Author

headius commented May 24, 2021

JarResource stores cache in a static field

This is still the case, and I am still unsure if it is safe.

The implementation is safe and the actual caches indices are stored weakly, so I think this is a non-issue.

IR Profiler uses static collections for much of its data gathering.

Still an issue but not a complete or supported feature and not enabled by default. Additional work can clean up static fields.

@headius
Copy link
Member Author

headius commented May 24, 2021

Calling this one resolved. Remaining static references are either non-issues or not part of supported/active code.

@headius headius closed this as completed May 24, 2021
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

No branches or pull requests

2 participants