Java Performance Tuning
Java(TM) - see bottom of page
Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks!
Training online: Concurrency, Threading, GC, Advanced Java and more ...
Tips December 2022
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 265 contents
https://www.youtube.com/watch?v=Vy1EbB2kBBs
What the CRaC Superfast JVM startup (Page last updated October 2022, Added 2022-12-29, Author Gerrit Grunwald, Publisher Devoxx). Tips:
- The JVM JIT does speculative optimization (based on branches used so far) and these optimization can be deoptimized if the previously unused branch becomes used. This means that warmups which don't exercise all the code paths that will be used in the full application, will likely cause deoptimizations to happen which will be seen as an application slowdown and higher CPU usage until the code is again fully optimized when the JVM sees it as a hot spot.
- Class Data Sharing (CDS) dumps the internal class representation can speed up your startup time.
- Ahead of time compilation (AOTC) compiles code before it is run can startup the application fast, but doesn't include runtime knowledge in the compilation optimizations, so doesn't produce the fastest JVM applications. You can also re-compile (with a JIT) for AOTC JVMs, but this is currently not yet producing optimal performance.
- CRaC (Coordinated Restore at Checkpoint) uses Linux CRIU but tries to handle the CRIU challenges (different machine restore, static PID, open handles to file system resources). CRaC uses JVM safepointing which means it is safe for multithreaded code.
- The additional JVM options for CRaC are -XX:CRaCCheckpointTo=PATH and -XX:CRaCRestoreFrom=PATH, and additional API options are Resource.beforeCheckpoint() and Resource.afterRestore() to let the application handle external resources (eg sockets, open files) across the checkpoint/restore boundary.
- The CRaC API flow is: 1 implement Resource.beforeCheckpoint()/afterRestore() for each resource you need to be restored; 2. register the resource implementation with Core.getGlobalContext().register(Resource). Note the registration ordering matters, the beforeCheckpoint() implementations are called in reverse order of registration, and the afterRestore() implementations are called in order of registration.
- CRaC Checkpointed applications will store timestamps at the time of checkpointing. If you have elapsed time dependent code, the restored application will see a very big elapsed delta. One way to workaround that is to take the timestamp at checkpoint, and the timestamp at restore, get the delta, and apply that to all the timestamps in the elapsed time dependent code at restore.
- Creating a CRaC checkpoint can be done from the command line with `jcmd NEWNAME.jar JDK.Checkpoint`, or in the code by calling Core.checkpointRestore().
- One way to decide when to checkpoint the fully normally running application is to wait until most of the compilations are done (eg seeing when output from -XX:+PrintCompilation is tailing off).
- You can use CRaC checkpoint saved applications saved in a docker container image to make the whole thing very contained and fast to startup.
https://www.youtube.com/watch?v=pGHN8a3VAeU
The fast startup landscape is expanding! (Page last updated October 2022, Added 2022-12-29, Author Dan Heidinga, Publisher Devoxx). Tips:
- Application startup time and resource costs matters more now because deployments are much more frequent than previously. Startup time could include building images, container copy, start and provisioning, JVM startup to main(), application dependencies loaded and initialized, application loaded and initialized, and then compilation optimizations and cache filling.
- CDS (class data sharing) and Shared Classes are available to make startup time faster by saving loaded class structures to a file, eliminating some of the classloading overhead for applications using that file - and reducing memory footprint by letting that be shared across JVMs on the same machine.
- Shift work from the runtime to build time. Frameworks like Quarkus and Micronaut have applied this approach to move initializations to build time. CRaC provides a way to store the application after startup, but you need to decide when the optimal time is to store. But CRaC is an option for moving from runtime to build time.
- OpenJDK CRaC and OpenJ9 Semeru InstantOn use Linus CRIU to enable the application to be stored after startup, so making for a faster startup if the stored image is used. But concerns include that: things are initialized at build time (before checkpointing) that you you don't want to initialize, like Random/SecureRandom, timestamps, the value of environment variables, the hardware resources (eg number of CPUs).
- With a CRaC checkpointed application, you often want lazily initialized objects to become early initialized (before checkpointing)!
https://www.youtube.com/watch?v=R7cXo8YHKe4
Techniques for a faster JVM start-up (Page last updated October 2022, Added 2022-12-29, Author Ionut Balosin, Publisher Devoxx). Tips:
- There are three types of startups: cold startup - starting the JVM and app from scratch; warm startup - the JVM is running but the app has not been started (it may be initialized); hot startup - the app was already running but was paused and not gets unpaused.
- Cold start optimization techniques: Class Data Sharing in OpenJDK, Shared class cache in OpenJ9, Ahead of time compilation eg Graal native image, OpenJDK CRaC (saved image), OpenJDK Leyden (static binaries), Alibaba Dragonwell JWarmUp, jlink/jpackage removed modules.
- Class Data Sharing (CDS) in OpenJDK caches preprocessed core Java classes & metadata in a file in a format that is loaded very quickly, on by default (with a class archive already present in the distribution since JDK 12). AppCDS let's you do the same for your app classes, in three steps - list the classes, save the class archive, use the class archive. DynamicCDS (since JDK13) eliminates the first list step in AppCDS -XX:ArchiveClassesAtExit=..; -XX:SharedArchiveFile=... let's you include multiple archives.
- Shared class cache in OpenJ9 is a memory mapped file that stores core Java classes, profile data, JIT compiled code, and more. Only URLClassLoader (and subclasses) loaded classes can be added, though there are also APIs to load custom classes. Use -Xshareclasses:... and you can add -Xquickstart but note that the latter flag could impact performance other than startup time.
Jack Shirazi
Back to newsletter 265 contents
Last Updated: 2025-01-27
Copyright © 2000-2025 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
URL: http://www.JavaPerformanceTuning.com/news/newtips265.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us