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