garbage collection and indy

Jochen Theodorou blackdrag at gmx.org
Wed Aug 23 08:09:59 UTC 2023



Am 22.08.23 um 22:38 schrieb Charles Oliver Nutter:
> On Tue, Aug 22, 2023 at 3:07 PM Jochen Theodorou <blackdrag at gmx.org> wrote:
>> Is there any possible circumstance in which the class Foo can now be
>> garbage collected? My assumption is no.
>
> I can't speak to varhandles but this is very much like how JRuby
> handles all of our jitted Ruby methods and indy binding. Under normal
> circumstances, most Ruby methods get jit-compiled to bytecode lazily
> and loaded into a unique classloader each; that classloader is not
> rooted anywhere, so that if the Ruby method goes away, the jitted
> class can also go away.

But don't you get problems with the method going away and then being
required again?

> If the method was transient in the Ruby world (e.g. created on a
> "singleton" object that goes out of scope) but is still bound at a
> call site, it will not get garbage collected. We've actually had some
> "won't fix" bug reports about indy call sites rooting methods or
> classes that were called once (as is our expectation, not a bug).

I can maybe actually make my description more clear with an example in
pseudo Java:

'''
class ScriptRunner {
   public runScript10times(String script) {
     Object instance = compileJava(script)
     for (int i=0; i<10; i++) {
       instance.getClass().getMethod("run").invoke(instance)
     }
   }
}
'''

where compileJava will compile the script into bytecode and load it
under the assumption that it is a run() method. The script could be
normal Java. Then compileJava would maybe leverage javac for this and a
bit of reflection and a classloader that is only for that class to be
defined in. Let us assume ScriptRunner will stay around for a long time
and the classloader used is not referenced anywhere.

Anyway... my assumption for Java would be now, that after the method
call is done:
* instance can be collected and is in fact pretty fast.
* since instance and classloader are not referenced, the script class is
becoming collectable
* the script class can be collected once GC gets to it.

Now let us assume ScriptRunner is almost Java, everything is the same,
but the call to run()
"instance.getClass().getMethod("run").invoke(instance)" is now done
using invokedynamic "instance.run()". Let us assume there will be a
runtime selection of the run method, that does something like the
pseudo-Java version, unreflects the method and invokes the handle as
well as installs it in the mutable callsite as target (with guards to
detect a new script class).

Then it seems to me like:
* instance can be collected like above
* the class will be hard/strong referenced by the MethodHandle instance
type information in the callsite
* the script class can be collected only once the callsite target is
rewritten or the class ScriptRunner goes away.

Am I wrong?


bye Jochen


More information about the mlvm-dev mailing list