<div dir="ltr">I created a reduced version of what we're seeing here:<br><br><a href="https://gist.github.com/DanielThomas/83eefaad41af33a071d9a9ee17ca8fe1">https://gist.github.com/DanielThomas/83eefaad41af33a071d9a9ee17ca8fe1</a><br><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 13, 2024 at 1:54 PM Calvin Cheung <<a href="mailto:calvin.cheung@oracle.com">calvin.cheung@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div>
<p>Hi Danny,<br>
</p>
<div>On 8/9/24 1:38 PM, Danny Thomas wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>I tried 24-leydenpremain+2-8 on a few internal
applications, some quick feedback below (good to see you folks
at the JVM LS!).<br>
</div>
</div>
</blockquote>
Thanks for trying the EA build.<br>
<blockquote type="cite">
<div dir="ltr">
<div><br>
If a jar has a Class-Path attribute and one or more of those
libraries are explicitly on the classpath, it causes the
actual and expected classpath to always differ. This is also
the case currently with CDS of course, but this feature is
sure to be deployed far more broadly than CDS is currently, so
likely something you want to look at:<br>
<br>
[0.057s][info][class,path] non-existent Class-Path entry
lib/failureaccess-1.0.1.jar<br>
[0.057s][info][class,path] opened:
lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar<br>
[0.057s][info][class,path] library =
lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar<br>
</div>
</div>
</blockquote>
<p>I couldn't reproduce the above Class-Path attribute issue with a
simple test[1]. The simple test was extracted from an existing
test case[2].</p>
<p>Can you provide a test case?</p>
<p>(I'll let others to answer the other issues.)<br>
</p>
Thanks,<br>
Calvin<br>
[1] <a href="https://cr.openjdk.org/~ccheung/cp-attribute/" target="_blank">https://cr.openjdk.org/~ccheung/cp-attribute/</a><br>
[2]
<a href="https://github.com/openjdk/jdk/blob/master/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java" target="_blank">https://github.com/openjdk/jdk/blob/master/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java</a><br>
<blockquote type="cite">
<div dir="ltr">
<div><br>
Startup time when training seems to be on par
with ArchiveClassesAtExit in JDK 21, but it's about a 3.5x
startup time penalty for one of our typical Spring Boot
applications. From a back-to-back run on my machine (AMD EPYC
9R14, 32 cores, 123G, Ubuntu 22.04.4 LTS):</div>
<div><br>
Started App in 7.698 seconds (process running for 8.229)<br>
Started App in 26.247 seconds (process running for 29.262) -
w/ CacheDataStore, Training Run<br>
Started App in 4.341 seconds (process running for 4.917) - w/
CacheDataStore, Production Run<br>
<br>
I also got a crash on one attempt, I can't remember what I did
to cause this unfortunately:<br>
<br>
Stack: [0x00007f3949ab0000,0x00007f3949bb0000],
sp=0x00007f3949bae628, free space=1017k<br>
Native frames: (J=compiled Java code, j=interpreted, Vv=VM
code, C=native code)<br>
V [libjvm.so+0x42ca30]
ArchiveBuilder::get_buffered_addr(unsigned char*) const+0x40<br>
V [libjvm.so+0xce4aa5]
VM_PopulateDumpSharedSpace::doit()+0x395<br>
V [libjvm.so+0x100ae69] VM_Operation::evaluate()+0x109<br>
V [libjvm.so+0x100e348]
VMThread::evaluate_operation(VM_Operation*)+0xe8<br>
V [libjvm.so+0x10142fb]
VMThread::inner_execute(VM_Operation*)+0x35b<br>
V [libjvm.so+0x101460f] VMThread::run()+0x16f<br>
V [libjvm.so+0xf6e5cf] Thread::call_run()+0x9f<br>
V [libjvm.so+0xd74e13] thread_native_entry(Thread*)+0x183<br>
C [libc.so.6+0x98b07]<br>
<br>
siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR),
si_addr: 0x0000000000000030<br>
<br>
</div>
<div>Thinking ahead to operationalizing AOT, while a
single-shot/on-exit workflow is great for iterating locally,
requiring the VM to exit makes this more difficult to
operationalize at scale:<br>
<ol>
<li>We'll perform training and assembly on test, production
canary and production instances on behalf of application
owners and handle distribution of the archives. Depending
on when we're able to perform a training run, it'll have
different benefits. i.e.:</li>
<ol>
<li>Test environment will at least improve startup
performance, with a mixed benefit for warm up depending
on the kind of traffic they take in test</li>
<li>If an application uses canary deployments we'll have a
full production profile prior to the full production
deployment, and all instances will come up hot</li>
<li>If we reach production with only a test environment
profile, we'll perform a training run in production, so
instances that scale up following that run will come up
hot (completely cold instances for an initial deployment
is less of a concern, because we deploy immutably and
get a natural warm-up period while we have 200% capacity
online for a cluster)</li>
</ol>
<li>It's currently not a problem if a VM doesn't exit
completely due to a dangling non-daemon thread or hung
shutdown hook</li>
</ol>
<div>Being able to trigger assembly/verification via jcmd
without exiting, would make this far easier for us to
support. If the overhead of the instrumentation for CDS
can be avoided, being able to take a snapshot at any time on
any VM would be better still, but that wouldn't be an
impediment for us: we'll know that the instance will be used
for training at boot time.<br>
<br>
We build nightlies of all the currently active OpenJDK
projects, so if you land anything on premain between EA
builds that you'd like us to try, let us know!<br>
<br>
Cheers,<br>
Danny</div>
</div>
</div>
</blockquote>
</div>
</blockquote></div>