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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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!
    ♥️

    View Slide

  7. Demo: your first Micronaut app
    Copyright © 2022
    8

    View Slide

  8. Copyright © 2022, Oracle and/or its affiliates
    9

    View Slide

  9. Copyright © 2022, Oracle and/or its affiliates
    10

    View Slide

  10. Copyright © 2022, Oracle and/or its affiliates
    11

    View Slide

  11. Micronaut AOT
    Copyright © 2021, Oracle and/or its affiliates
    12

    View Slide


  12. 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

    View Slide

  13. Demo: optimizing your Micronaut app
    Copyright © 2022, Oracle and/or its affiliates
    14

    View Slide

  14. Copyright © 2022, Oracle and/or its affiliates
    15
    Add the Micronaut AOT
    plugin
    Configure
    optimizations

    View Slide

  15. Copyright © 2022, Oracle and/or its affiliates
    16

    View Slide

  16. Copyright © 2022, Oracle and/or its affiliates
    17

    View Slide

  17. Copyright © 2022, Oracle and/or its affiliates
    18

    View Slide

  18. Micronaut AOT
    Copyright © 2022, Oracle and/or its affiliates
    19

    View Slide

  19. 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

    View Slide

  20. 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

    View Slide


  21. 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

    View Slide

  22. public class StaticServicesLoader implements
    StaticOptimizations.Loader {
    @Override
    public SoftServiceLoader.Optimizations load() {
    Map> staticServices = new HashMapSoftServiceLoader.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

    View Slide


  23. 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

    View Slide


  24. 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

    View Slide

  25. 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

    View Slide

  26. Micronaut AOT: example impact on native
    Copyright © 2022, Oracle and/or its affiliates
    27

    View Slide

  27. Micronaut AOT: example impact on native
    Copyright © 2022, Oracle and/or its affiliates
    28

    View Slide


  28. 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

    View Slide


  29. 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

    View Slide

  30. 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 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 findMissingClasses(List classNames) {
    List 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

    View Slide


  31. 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

    View Slide


  32. 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

    View Slide

  33. Copyright © 2022, Oracle and/or its affiliates
    34
    Thank you!
    Slides coming at @CedricChampeau

    View Slide