Question about Reflection details

David Holmes david.holmes at oracle.com
Tue May 15 11:45:29 UTC 2018


Hi Thomas,

This is really a core-libs question not a hotspot one.

On 15/05/2018 8:06 PM, Thomas Stüfe wrote:
> Hi all,
> 
> I have two questions about the non-native reflection mechanism in the VM:
> 
> 1) For each method invocation we generate a new child class of
> internal.reflect.MagicAccessorImpl, which is loaded by its own
> instance of DelegatingClassLoader.
> 
> The comment in jdk.internal.reflect.ClassDefiner states the reasons for this:
> 
> <quote>
> There are two primary reasons for creating a new loader
> instead of defining these bytecodes directly into the defining
> loader of the target class: first, it avoids any possible
> security risk of having these bytecodes in the same loader.
> Second, it allows the generated bytecodes to be unloaded earlier
> than would otherwise be possible, decreasing run-time
> footprint.
> </quote>
> 
> Do I understand this correctly:
> 
> the lifetime of the MagicAccessorImpl instance, its class and its
> loading DelegatingClassLoader are defined by the lifetime of the
> java.lang.reflect.Method/Constructor object which keeps the
> MagicAccessorImpl instance in its methodAccessor/constructorAccessor
> field?
> 
> So, if that Method/Constructor object is collected, its
> MagicAccessorImpl instance is collected, and since it is the only
> instance its class too, and since it is the only class in that
> DelegatingClassLoader that gets collected as well?

Yes. If we didn't use new classloaders we'd accumulate these generated 
classes and never be able to unload them.

> 
> 2) I see in my traces that for each Method.invoke(obj.foo()) we generate
>    - one GeneratedMethodAccessorImplXXX class living in its own
> DelegatingClassLoader instance, which invokes obj.foo
>    - and then one additional GeneratedConstructorAccessorXXX, again
> living in its very own DelegatingClassLoader instance, which invokes
> the constructor for the just generated GeneratedMethodAccessorImplXXX.

That's a level of detail I'd have to go and look up. :)

> The latter I see only if I switch off inflation. The very first (and
> only) time GeneratedMethodAccessorImplXXX is instantiated it will
> cause GeneratedConstructorAccessorXXX to be created for that one
> newInstance() call.
> 
> But surely, in that case we could save one class loader and let the
> GeneratedConstructorAccessorXXX get loaded by the
> DelegatingClassLoader which also loaded the associated
> GeneratedMethodAccessorImplXXX? Or is it too much bother, since we are
> in an artificial scenario (noInflation=true)?

Don't know.

> ----
> 
> In general, I have the following question:
> 
> Will the 1:1 relationship between MagicAccessorImpl class and
> DelegatingClassLoader instance always hold true?
> 
> Or is there work in progress somewhere which would maybe bundle
> MagicAccessorImpl classes in one loader (e.g. (2) would be a candidate
> for this), or maybe do it without loaders?

I'm not aware of any impending changes in this area, but it is a pretty 
old area ... the new reflection was added in 1.4. You could say that 
this core reflection is legacy and that MethodHandles should be used 
instead.

As I said really a question for core-libs.

Cheers,
David

> Thanks!
> 
> Thomas
> 


More information about the hotspot-runtime-dev mailing list