Redundant MethodCounters in preimage

Ashutosh Mehra asmehra at redhat.com
Thu Dec 4 22:15:27 UTC 2025


FYI I have opened https://bugs.openjdk.org/browse/JDK-8373114 to fix it.

Thanks,
- Ashutosh Mehra


On Thu, Dec 4, 2025 at 4:01 AM María Arias de Reyna Dominguez <
mariasde at redhat.com> wrote:

> Hi!
>
> Note that there are MethodCounters added on the assembly run that don't
> have a MethodTrainingData associated. Maybe because those MethodCounters
> were created during the assembly? And then they don't reflect behaviour
> during training run but during assembly run? Or they are added via some
> other link? I don't know. But in any case, if we don't want MethodCounters
> with a low count value/with no MethodTrainingData, and we are excluding
> them from the AOT, we should be consistent with that.
>
> Example:
>
> $ grep -r "boolean java.lang.Class.isHidden()" aot.map*
> target/aot.map:0x00000008014c6340: @@ Method            104 boolean
> java.lang.Class.isHidden()
> target/aot.map:0x00000008014c63a8: @@ MethodCounters    64 boolean
> java.lang.Class.isHidden()
> target/aot.map:0x0000000803149908: @@ ConstMethod       64 boolean
> java.lang.Class.isHidden()
> target/aot.map.0:0x00000008015b23f0: @@ Method            104 boolean
> java.lang.Class.isHidden()
> target/aot.map.0:0x00000008015b2458: @@ MethodCounters    64 boolean
> java.lang.Class.isHidden()
> target/aot.map.0:0x00000008031d5430: @@ ConstMethod       64 boolean
> java.lang.Class.isHidden()
>
> It appears in both aot.map files (outputs of training and assembly).
>
> Cheers!
> María.
>
>
> On Thu, Dec 4, 2025 at 4:55 AM Ashutosh Mehra <asmehra at redhat.com> wrote:
>
>> Hi,
>> While working on the leyden-analyzer tool Maria mentioned that
>> MethodCounters for a particular method is present in the preimage generated
>> by the training run but not in the final AOT Cache generated by the
>> assembly phase. In fact the number of MethodCounters in the preimage is way
>> more than that in the final image. For an app that Maria was using, map
>> file for training phase shows:
>>
>> $ grep "@@ MethodCounters " t.map |wc -l 22495
>>
>> and the map file for assembly phase shows:
>>
>> $ grep "@@ MethodCounters " a.map |wc -l 8701
>>
>> I checked the code and realized there are two ways MethodCounters can get
>> into the cache:
>> 1. through Method (see Method::metaspace_pointers_do)
>> 2. through MethodTrainingData
>> (see MethodTrainingData::metaspace_pointers_do)
>>
>> The first point explains the presence of so many MethodCounters, because
>> any method that gets executed would have its MethodCounters added to the
>> cache.
>> Interestingly the link between Method and MethodCounters is then severed
>> in Method::unlink_method(). That means the Methods adopted from the
>> preimage in the assembly phase do not have MethodCounters. And since we
>> don't execute the application, we don't create MethodCounters for the
>> Methods loaded from the preimage. Only the MethodCounters discoverable via
>> MethodTrainingData seep into the AOTCache.
>>
>> From the above explanation it looks like not every MethodCounters added
>> to the preimage is useful. Probably we should only be adding MethodCounters
>> through the MethodTrainingData and not through Method. This would also
>> reduce the size of the preimage a bit. In this particular case
>> MethodCounters size was 1437824 bytes in preimage and 551552 bytes in the
>> AOT Cache.
>>
>> Does this make sense?
>>
>> Thanks,
>> - Ashutosh Mehra
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/leyden-dev/attachments/20251204/5db2f0a3/attachment.htm>


More information about the leyden-dev mailing list