Iqbal´s DLQ main Help

Profile Guided Optimization

After we restored tracing capability in Tracing in native image - Datadog

Let's take a look at Profile guided optimization (PGO).

this technique allows you to generate a profile at runtime of optimizations that the JVM applies and bring them to build time for your next native image build.

You will need GraalVM Enterprise Edition for PGO builds.

Setup

the first thing we need is to build a native image capable of collecting runtime data

As in previous articles, we use the native image maven plugin to pass the arguement <arg>--pgo-instrument</arg>:

<!--...--> <buildArgs> <arg>-J-javaagent:dd-java-agent.jar</arg> <arg>--pgo-instrument</arg> <arg>--initialize-at-run-time=sun.net.dns.ResolverConfigurationImpl</arg> </buildArgs> <!--...-->

Build with

mvn -Pnative package -DskipTests

Check the logs for Active PGO instrumentation:

pgo_active.png

Notably

I ran out of memory trying to build a PGO instrumented native image:

[3/8] Building universe... (10.1s @ 4.38GB) [4/8] Parsing methods... [**] (4.8s @ 4.71GB) [5/8] Inlining methods... [**] (0.5s @ 4.80GB) [6/8] Compiling methods... [****************] (259.4s @ 7.40GB) GC warning: 170.0s spent in 1126 GCs during the last stage, taking up 65.53% of the time. Please ensure more than 9.35GB of memory is available for Native Image to reduce GC overhead and improve image build time. Terminating due to java.lang.OutOfMemoryError: Java heap space The Native Image build process ran out of memory. Please make sure your build system has more memory available.

The process took longer from the usual 8 minutes I was getting with -Ob quick build mode:

pgo_build_success.png

The binary generated was larger:

pgo_vs_nonpgo.png

Collect

During this phase, you would ideally use workloads similar to your production environment.

I will just send hundreds of queries through Postman's Collection runs

spring_profiles_active=local DD_SERVICE=native_tst ./pgo_instrumented_app.exe

this generates a profile default.iprof that we will use in the next step:

default_iprof.png

Pass to Native Image the profile

Pass the --pgo argument passed to the native image build tool:

<!--...--> <buildArgs> <arg>-J-javaagent:dd-java-agent.jar</arg> <arg>--pgo=default.iprof</arg> </buildArgs> <!--...-->

Rebuild:

mvn -Pnative package -DskipTests

Check for Active PGO:

pgo_active_build.png

Reference

Last modified: 22 January 2025