Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Micronaut AOT: optimiser vos application pour le JIT et GraalVM

Micronaut AOT: optimiser vos application pour le JIT et GraalVM

Cédric Champeau

April 21, 2022
Tweet

More Decks by Cédric Champeau

Other Decks in Technology

Transcript

  1. Micronaut AOT Optimizing your apps for the JIT and GraalVM

    Cédric Champeau Micronaut Developer Oracle Labs
  2. • Working at Oracle Labs on Micronaut • Main focus

    on build plugins and dev productivitity • Formerly working at Gradle Inc • Author of static compiler of Groovy • Amateur astronomer • @CedricChampeau • https://www.astrobin.com/users/melix/ About me Copyright © 2021, Oracle and/or its affiliates micronaut.io github.com/micronaut-projects/micronaut-core
  3. • Micronaut is focused on modern architectures like Serverless and

    Microservices • Also a complete framework for any type of application • Lightweight, reactive (HTTP Client/Server based on Netty) • Annotation processor to compute framework infrastructure at compile time Micronaut Copyright © 2021, Oracle and/or its affiliates micronaut.io github.com/micronaut-projects/micronaut-core
  4. Micronaut = Build Time Framework Infrastructure Copyright © 2021, Oracle

    and/or its affiliates Micronaut computes: • All dependency & configuration injection • Annotation metadata, meta-annotations • AOP proxies • Bean introspections • And all other framework infrastructure • Reflection, runtime proxy, and dynamic classloader free
  5. GraalVM Copyright © 2021, Oracle and/or its affiliates • High-performance

    JDK distribution • Increases application throughput, reduces latency, reduces memory use • Graal just-in-time (JIT) compiler that runs on top of HotSpot, written in Java • native-image ahead-of-time (AoT) compiler compiles Java applications into small self- contained native binaries graalvm.org github.com/graalvm/graalvm-demos oracle.com/graalvm
  6. Micronaut GraalVM ♥️ Copyright © 2021, Oracle and/or its affiliates

    • Micronaut + GraalVM Native Image are a match made in heaven • Less work to configure Native Image because Micronaut eliminates reflection, runtime proxies, bytecode generation and dynamic classloading • Startup time 20ms and Memory Consumption 18MB! ♥️
  7.  Optional extension to the Micronaut framework  Available via

    build tool plugins (Gradle, Maven or CLI invocation)  Performs deployment optimizations  Generates an application which is tailored to a particular deployment environment  Generates distinct optimizations for the “regular” JVM (aka “JIT mode”) or native (aka “GraalVM”)  Can optimize  CLI applications  HTTP applications  Functions (currently tested with AWS Lambda and Oracle Cloud Functions, Azure coming) Micronaut AOT Copyright © 2022, Oracle and/or its affiliates 13
  8. Copyright © 2022, Oracle and/or its affiliates 15 Add the

    Micronaut AOT plugin Configure optimizations
  9. Building an application without Micronaut AOT Copyright © 2022, Oracle

    and/or its affiliates 20 Sources (.java, .groovy, .kt) class files javac + Annotation processing Resources (.yaml, .properties) Jar file packaging packaging Native binary native-image
  10. Building an application with Micronaut AOT Copyright © 2022, Oracle

    and/or its affiliates 21 jar file (or classes + resources) class files AOT jar file Native AOT binary native-image Resource files Source files Metadata filtering AOT analysis
  11.  Optimizing service loading  pre-scans META-INF/service files (for some

    core types) and generates classes which avoid the use of service loader and permits parallel loading  Generated loaders are different in JIT and native!  Converting YAML files to Java  Avoids parsing YAML files at application startup  Reduces the size of the generated native binary  Caching the environment  Once the application is started, all environment variables and system properties are deemed immutable  Pre-computing bean requirements  Evaluates @Requires conditions at build time instead of runtime  Reduces the size of the generated native binary Micronaut AOT Core Optimizations Copyright © 2022, Oracle and/or its affiliates 22
  12. public class StaticServicesLoader implements StaticOptimizations.Loader<SoftServiceLoader.Optimizations> { @Override public SoftServiceLoader.Optimizations load()

    { Map<String, SoftServiceLoader.StaticServiceLoader<?>> staticServices = new HashMap<String, SoftServiceLoader.StaticServiceLoader<?>>(); staticServices.put("io.micronaut.context.env.PropertySourceLoader", new PropertySourceLoaderFactory()); staticServices.put("io.micronaut.http.HttpResponseFactory", new HttpResponseFactoryFactory()); staticServices.put("io.micronaut.inject.BeanDefinitionReference", new BeanDefinitionReferenceFactory()); staticServices.put("io.micronaut.core.beans.BeanIntrospectionReference", new BeanIntrospectionReferenceFactory()); staticServices.put("io.micronaut.inject.BeanConfiguration", new BeanConfigurationFactory()); staticServices.put("io.micronaut.http.HttpRequestFactory", new HttpRequestFactoryFactory()); return new SoftServiceLoader.Optimizations(staticServices); } } Micronaut AOT: Code generation Copyright © 2022, Oracle and/or its affiliates 23
  13.  Optimizing classloading  Performs Class#forName at build time to

    avoid ClassNotFoundException at run time  Deducing the environment at build time  Performs the “environment deduction” (AWS, Google Cloud, …) at build time instead of run time  Precomputing “expensive operations”  Pre-computes some constants at build-time instead of run time  For example, the mapping between environment variable names and Micronaut properties  (Experimental) Converting logback.xml to Java configuration  Avoids loading the XML parsing library at application startup Micronaut AOT Core Optimizations Copyright © 2022, Oracle and/or its affiliates 24
  14.  Faster startup time  10% faster, sometimes more depending

    on your context  Smaller native images  By substitution, some classes are not reachable anymore  Results depend on the transitive dependency graph  Improved time to first request  Module specific optimizations can access resources at build time Micronaut AOT: what benefits to expect? Copyright © 2022, Oracle and/or its affiliates 25
  15. graalvmNative { binaries.all { // profiling buildArgs.add("-H:-DeleteLocalSymbols") buildArgs.add("-H:+PreserveFramePointer") } }

    Micronaut AOT: profiling native applications Copyright © 2022, Oracle and/or its affiliates 26
  16.  Micronaut Serialization  Provides compile-time databinding  Replacement for

    Jackson Databind  Runtime can use Jackson, BSON or JSON-P Impact on image size Copyright © 2022, Oracle and/or its affiliates 29
  17.  Micronaut AOT supports plugins  Plugins are “source generators”

    which get access to the application context  Generated code can inject optimizations into Micronaut via dedicated API  Plugins contribute new optimizations  Eg: Micronaut Security can fetch OpenID metadata configuration from remote at build time. Can save up to 1s at the first request!  Code generators execute within the context of the target application! Micronaut AOT extensibility Copyright © 2022, Oracle and/or its affiliates 30
  18. Micronaut AOT extensibility Copyright © 2022, Oracle and/or its affiliates

    31 @Override public void generate(@NonNull AOTContext context) { context.registerStaticOptimization("KnownMissingTypesOptimizationLoader", ClassUtils.Optimizations.class, body -> { List<String> classNames = context.getConfiguration().stringList(OPTION.key()); body.addStatement("$T knownMissingTypes = new $T()", ParameterizedTypeName.get(Set.class, String.class), for (String knownMissingClass : findMissingClasses(classNames)) { body.addStatement("knownMissingTypes.add($S)", knownMissingClass); } body.addStatement("return new $T(knownMissingTypes)", ClassUtils.Optimizations.class); }); } private List<String> findMissingClasses(List<String> classNames) { List<String> knownMissingClasses = new ArrayList<>(); ClassLoader cl = this.getClass().getClassLoader(); for (String name : classNames) { try { cl.loadClass(name); } catch (ClassNotFoundException | NoClassDefFoundError e) { knownMissingClasses.add(name); } } return knownMissingClasses; } This happens in user application context
  19.  Micronaut is a modern framework which uses build-time optimizations

    • Use of annotation processing for generating metadata, avoiding reflection, …  Micronaut AOT complements the approach • Not everything can be done by annotation processing • Substitution of classes/resources • Parsing configuration files • Sensitive to the build environment and therefore sensitive to the deployment environment Conclusion Copyright © 2022, Oracle and/or its affiliates 32
  20.  Micronaut Website • https://micronaut.io  Micronaut Launch • Bootstrap

    your Micronaut apps: https://micronaut.io/launch  Micronaut AOT • Documentation: https://micronaut-projects.github.io/micronaut-aot/latest/ • Gradle plugin: https://micronaut-projects.github.io/micronaut-gradle-plugin/latest/#_micronaut_aot_plugin • Maven plugin: https://micronaut-projects.github.io/micronaut-maven-plugin/latest/examples/aot.html  GraalVM Community Edition • https://www.graalvm.org/ Links Copyright © 2022, Oracle and/or its affiliates 33