Question about Reflection details
Thomas Stüfe
thomas.stuefe at gmail.com
Tue May 15 12:19:06 UTC 2018
Thank you David!
I will take a closer look at MethodHandles and how they are
implemented. And I will redirect this question to core-libs.
Best Regards, Thomas
On Tue, May 15, 2018 at 1:45 PM, David Holmes <david.holmes at oracle.com> wrote:
> 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