premain: negative lookup cache for class loaders

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Tue Jan 23 23:05:48 UTC 2024


Good point, Sebastien. I wasn't aware lookup caches are part of 
AOT-preprocessing Spring does.

I made a quick experiment with PetClinic and observed the following 
behavior for Class.forName [1]:

   * -Dspring.aot.enabled=false: 792 exceptions thrown (293 unique names)

   * -Dspring.aot.enabled=true:  512 exceptions thrown (141 unique names)


Speaking of requests originated in 
org/springframework/util/ClassUtils.isPresent():

   * -Dspring.aot.enabled=false: 251 exceptions thrown (151 unique names)

   * -Dspring.aot.enabled=true:   63 exceptions thrown (41 unique names)


Still, the accumulated time spent in Class.forName() hints that positive 
lookups dominate negative ones:

Baseline (23-ea):

-Dspring.aot.enabled=false:  127ms (15873 events)
-Dspring.aot.enabled=true:    78ms (10185 events)


Leyden/premain deployment run:

-Dspring.aot.enabled=false: 37ms (15859 events)
-Dspring.aot.enabled=true:  18ms (10171 events)

Best regards,
Vladimir Ivanov

[1] https://gist.github.com/iwanowww/395f1be2f4890641fbeacb35ff503b49

On 1/19/24 03:20, Sebastien Deleuze wrote:
> Hi,
> 
> The startup of a Spring Boot applications involves common 
> auto-configuration checks which would definitely benefit from negative 
> lookup caching at the ClassLoader level, quickly indicating which parts 
> of the infrastructure are not present at runtime.
> Spring AOT optimizations can precompute those checks, but involve side 
> effects and constraints that probably mean we won't enable them by 
> default for the foreseeable future. The Spring codebase also contains 
> various class presence checks like the ones in 
> WebMvcConfigurationSupport [1] that will be performed regardless of 
> Spring AOT optimizations, with typically more negative lookups than 
> positive ones.
> 
> Best regards,
> Sébastien Deleuze
> 
> [1] 
> https://github.com/spring-projects/spring-framework/blob/7e511931b305edc84eb04a219c277a6c8fdcba59/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java#L213-L227 <https://github.com/spring-projects/spring-framework/blob/7e511931b305edc84eb04a219c277a6c8fdcba59/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java#L213-L227>
> 
> On Tue, Jan 16, 2024 at 5:57 PM David Lloyd <david.lloyd at redhat.com 
> <mailto:david.lloyd at redhat.com>> wrote:
> 
>     On Thu, Jan 11, 2024 at 4:15 PM John Rose <john.r.rose at oracle.com
>     <mailto:john.r.rose at oracle.com>> wrote:
> 
>         __
> 
>         [...] But, a /failed/ lookup is not recorded anywhere. So every
>         distinct lookup must start again from first principles and fail
>         all over again. For some workloads this costs a small but
>         measurable percentage of startup time.
> 
>         The story is different for the local |CONSTANT_Class| entries in
>         any given classfile: The JVMS mandates that both successful and
>         failed lookups are recorded on the first attempt (per CP entry
>         per se, not globally and not per class). Global usage includes
>         both use of |Class.forName| and the “back end” logic for CP
>         entry resolution. CP resolution is performed at most once per CP
>         entry, and (win or lose) is made sticky on the CP itself, locally.
> 
>         To summarize, we can say that, for class lookup, both success
>         and failure are “sticky” locally, and success is “sticky”
>         globally, but failure is “not sticky” globally.
> 
>     We have implemented a negative lookup cache in the past in certain
>     of our middleware products' custom class loaders, and while they
>     *can* help, I seem to recall that we had some trouble with cache
>     explosion in some scenarios involving certain frameworks. We
>     abandoned that approach quite a long time ago though in favor of a
>     more optimized index-by-package scheme which ensures that all
>     lookups, success or failure, run in (more or less) constant time,
>     which had essentially eliminated the issue for us for that use case.
> 
>     FWIW I do think that it could be potentially nifty to constant-fold
>     negative lookup cases where that is possible.
> 
> 
>     -- 
>     - DML • he/him
> 
> 
> This electronic communication and the information and any files 
> transmitted with it, or attached to it, are confidential and are 
> intended solely for the use of the individual or entity to whom it is 
> addressed and may contain information that is confidential, legally 
> privileged, protected by privacy laws, or otherwise restricted from 
> disclosure to anyone else. If you are not the intended recipient or the 
> person responsible for delivering the e-mail to the intended recipient, 
> you are hereby notified that any use, copying, distributing, 
> dissemination, forwarding, printing, or copying of this e-mail is 
> strictly prohibited. If you received this e-mail in error, please return 
> the e-mail to the sender, delete it from your computer, and destroy any 
> printed copy of it.


More information about the leyden-dev mailing list