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

July 01, 2022
Tweet

More Decks by Cédric Champeau

Other Decks in Programming

Transcript

  1. Micronaut® AOT
    Optimizing your apps for the JIT and GraalVM
    Cédric Champeau
    OracleLabs
    @CedricChampeau
    Copyright © 22-7-1, Oracle and/or its affiliates
    Micronaut® is a registered trademark of Object Computing, Inc. Use is for referential purposes and does not
    imply any endorsement or affiliation with any third-party product. Unauthorized use is strictly prohibited.

    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. Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
    8
    Demo
    Your first Micronaut application

    View Slide

  8. View Slide

  9. View Slide

  10. View Slide

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

    View Slide

  12. Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
    13
    Micronaut AOT

    View Slide


  13. 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
    14

    View Slide

  14. Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
    15
    Demo
    Optimizing your Micronaut application

    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 © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
    18
    Micronaut AOT

    View Slide

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

    View Slide

  19. Building an application with Micronaut AOT
    Copyright © 2022, Oracle and/or its affiliates
    20
    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


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

    View Slide


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

    View Slide

  24. graalvmNative {
    binaries.all {
    // profiling
    buildArgs.add("-H:-DeleteLocalSymbols")
    buildArgs.add("-H:+PreserveFramePointer")
    }
    }
    Micronaut AOT: profiling native applications
    Copyright © 2022, Oracle and/or its affiliates
    25

    View Slide

  25. Micronaut AOT: example impact on native
    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 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
    28

    View Slide


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

    View Slide

  29. Micronaut AOT extensibility
    Copyright © 2022, Oracle and/or its affiliates
    30
    @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


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

    View Slide


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

    View Slide

  32. View Slide