### Install SapMachine on Debian/Ubuntu using new-style repository Source: https://sapmachine.io/docs/installation Adds the SapMachine Debian repository using the modern DEB822 format with a dedicated keyring, then installs the JDK via apt. Recommended setup. ```bash sudo wget -qO /usr/share/keyrings/sapmachine.gpg https://dist.sapmachine.io/debian/sapmachine.gpg sudo wget -qO /etc/apt/sources.list.d/sapmachine.sources https://dist.sapmachine.io/debian/sapmachine.sources sudo apt-get update && sudo apt-get install sapmachine-25-jdk ``` -------------------------------- ### Install SapMachine on Alpine using apk Source: https://sapmachine.io/docs/installation Imports the public key, adds the SapMachine Alpine repository, and installs the JDK using the apk package manager. ```bash wget -qO /etc/apk/keys/sapmachine-apk.rsa.pub https://dist.sapmachine.io/alpine/sapmachine-apk.rsa.pub echo "https://dist.sapmachine.io/alpine" >> /etc/apk/repositories apk add sapmachine-25-jdk ``` -------------------------------- ### Install SapMachine on RPM-based systems using zypper Source: https://sapmachine.io/docs/installation Imports the public key, adds the SapMachine RPM repository, and installs the JDK using the zypper package manager. ```bash sudo rpm --import https://dist.sapmachine.io/rpm/sapmachine.key sudo curl -L -o /etc/zypp/repos.d/sapmachine-suse.repo https://dist.sapmachine.io/rpm/sapmachine-suse.repo sudo zypper --gpg-auto-import-keys refresh sudo zypper install -y sapmachine-25-jdk ``` -------------------------------- ### Install SapMachine on RPM-based systems using yum Source: https://sapmachine.io/docs/installation Imports the public key, adds the SapMachine RPM repository, and installs the JDK using the yum package manager. ```bash sudo rpm --import https://dist.sapmachine.io/rpm/sapmachine.key sudo curl -L -o /etc/yum.repos.d/sapmachine.repo https://dist.sapmachine.io/rpm/sapmachine.repo sudo yum install -y sapmachine-25-jdk ``` -------------------------------- ### Install SapMachine JDK cask with Homebrew Source: https://sapmachine.io/docs/installation Installs a SapMachine JDK cask using Homebrew, for example sapmachine25-jdk. ```bash brew install --cask sapmachine25-jdk ``` -------------------------------- ### Install latest SapMachine with Homebrew Source: https://sapmachine.io/docs/installation Installs the latest SapMachine JDK using Homebrew on macOS. Requires Homebrew to be installed first. ```bash brew update brew install sapmachine-jdk ``` -------------------------------- ### Install SapMachine with SDKMAN! Source: https://sapmachine.io/docs/installation Use this command to install SapMachine 25.0.4 via SDKMAN!. The SDKMAN! version string abbreviates SapMachine as 'sapmchn' due to length limits. ```bash # Install SapMachine 25.0.4 with SDKMAN! sdk install java 25.0.4-sapmchn ``` -------------------------------- ### Start VM with JMC agent XML configuration Source: https://sapmachine.io/docs/jmc-agent-integration Starts the VM with a specific JMC agent XML configuration. Enables the trace, but since JFR events are not written by default, no output will be generated. ```bash java -jmcagent: ``` -------------------------------- ### Install specific SapMachine version via Homebrew tap Source: https://sapmachine.io/docs/installation Adds the SapMachine tap and installs a specific SapMachine version (e.g., 25) using Homebrew. ```bash brew tap sap/sapmachine brew install sapmachine25-jdk ``` -------------------------------- ### Install SapMachine on Debian/Ubuntu using old-style repository (deprecated) Source: https://sapmachine.io/docs/installation Adds the SapMachine Debian repository using the deprecated old-style format. This repository will no longer be available after 2026-12-30; migrate to the new-style repository. ```bash wget -qO- https://dist.sapmachine.io/debian/sapmachine.key > /etc/apt/trusted.gpg.d/sapmachine.asc echo "deb https://dist.sapmachine.io/debian/$(dpkg --print-architecture)/ ./" > /etc/apt/sources.list.d/sapmachine.list apt-get update apt-get install sapmachine-25-jdk ``` -------------------------------- ### Example converter class with convert() and overloaded methods Source: https://sapmachine.io/docs/jmc-agent-integration Example converter class with a static convert() method and an overloaded static method. Used to illustrate how converters are specified in , , and entries. ```java public class Converter { static String convert(int i) { return "" + i; } static float convertToFloat(int i) { return (float) i; } static String overloadedMethod(Object o) { return o.toString(); } static int overloadedMethod(Integer i) { return i; } } ``` -------------------------------- ### Start JMC agent with flight recording Source: https://sapmachine.io/docs/jmc-agent-integration Starts the trace and writes JFR events to the specified . The file can later be inspected with Java Mission Control or the jfr program shipped with SapMachine. ```bash java -jmcagent: -XX:StartFlightRecording=filename= ``` -------------------------------- ### Pull SapMachine images with tag components Source: https://sapmachine.io/docs/docker-images Examples of pulling SapMachine images with various tag components. The gl- prefix marks the Garden Linux version component. Pinning to specific versions is possible but should be accompanied by automated version bumps for security updates. ```bash # Latest SapMachine JDK on latest Garden Linux (implicit :latest) podman pull ghcr.io/sap/sapmachine # Latest SapMachine 25 JDK on latest Garden Linux podman pull ghcr.io/sap/sapmachine:25 # SapMachine 25.0.4 headless JRE on latest Garden Linux podman pull ghcr.io/sap/sapmachine:25.0.4-jre-headless # SapMachine 25 JDK pinned to a specific Garden Linux version podman pull ghcr.io/sap/sapmachine:25-jdk-gl-2150.4.0 ``` -------------------------------- ### Example output of HiMemReportDir with HiMemReportExec Source: https://sapmachine.io/docs/high-memory-reports Shows the files generated in the specified directory when using -XX:HiMemReportDir and -XX:HiMemReportExec. The base report is named sapmachine_himemalert_pid_.log, and jcmd output files are named __.(out|err). ```bash thomas@starfish$ ls -al /tmp/himem/ total 176 drwxr-xr-x 2 thomas thomas 4096 Jun 17 15:56 . drwxrwxrwt 26 root root 36864 Jun 17 15:56 .. -rw-rw-r-- 1 thomas thomas 2485 Jun 17 15:56 sapmachine_himemalert_pid11015_2022_06_17_15_56_13.log -rw-rw-r-- 1 thomas thomas 0 Jun 17 15:56 VM.flags_pid11015_2022_06_17_15_56_13.err -rw-rw-r-- 1 thomas thomas 63568 Jun 17 15:56 VM.flags_pid11015_2022_06_17_15_56_13.out -rw-rw-r-- 1 thomas thomas 0 Jun 17 15:56 VM.info_pid11015_2022_06_17_15_56_13.err -rw-rw-r-- 1 thomas thomas 60764 Jun 17 15:56 VM.info_pid11015_2022_06_17_15_56_13.out ``` -------------------------------- ### Example SapMachine Vitals report output Source: https://sapmachine.io/docs/vitals Shows the format of a Vitals report, listing system, process, and JVM metrics with annotations for platform-specific values. The report header includes the Vitals version and process ID. The last section shows the last 60 minutes of data. ```text ------------system------------ avail: Memory available without swapping [host] comm: Committed memory [host] crt: Committed-to-Commit-Limit ratio (percent) [host] swap: Swap space used [host] si: Number of pages swapped in [host] [delta] so: Number of pages pages swapped out [host] [delta] p: Number of processes t: Number of threads tr: Number of threads running tb: Number of threads blocked on disk IO cpu-us: CPU user time [host] cpu-sy: CPU system time [host] cpu-id: CPU idle time [host] cpu-st: CPU time stolen [host] cpu-gu: CPU time spent on guest [host] cgroup-lim: cgroup memory limit [cgrp] cgroup-slim: cgroup memory soft limit [cgrp] cgroup-usg: cgroup memory usage [cgrp] cgroup-kusg: cgroup kernel memory usage (cgroup v1 only) [cgrp] mload: percentage of physical memory in use [windows] avail-phys: physical memory available [windows] wset: working set size [windows] comch: Commit charge [windows] -----------process------------ virt: Virtual size rss-all: Resident set size, total rss-anon: Resident set size, anonymous memory [krn] rss-file: Resident set size, file mappings [krn] rss-shm: Resident set size, shared memory [krn] swdo: Memory swapped out cheap-usd: C-Heap, in-use allocations [glibc] cheap-free: C-Heap, bytes in free blocks [glibc] cpu-us: Process cpu user time cpu-sy: Process cpu system time io-of: Number of open files io-rd: IO bytes read from storage or cache io-wr: IO bytes written thr: Number of native threads -------------jvm-------------- heap-comm: Java Heap Size, committed heap-used: Java Heap Size, used meta-comm: Meta Space Size (class+nonclass), committed meta-used: Meta Space Size (class+nonclass), used meta-csc: Class Space Size, committed [cs] meta-csu: Class Space Size, used [cs] meta-gctr: GC threshold code: Code cache, committed nmt-mlc: Memory malloced by hotspot [nmt] nmt-map: Memory mapped by hotspot [nmt] nmt-gc: NMT "gc" (GC-overhead, malloc and mmap) [nmt] nmt-oth: NMT "other" (typically DBB or Unsafe.allocateMemory) [nmt] nmt-ovh: NMT overhead [nmt] jthr-num: Number of java threads jthr-nd: Number of non-demon java threads jthr-cr: Threads created [delta] jthr-st: Total reserved size of java thread stacks [nmt] [linux] cldg-num: Classloader Data cldg-anon: Anonymous CLD cls-num: Classes (instance + array) cls-ld: Class loaded [delta] cls-uld: Classes unloaded [delta] [host]: values are host-global (not containerized). [cgrp]: if containerized or running in systemd slice [krn]: depends on kernel version [glibc]: only shown for glibc-based distros [delta]: values refer to the previous measurement. [nmt]: only shown if NMT is available and activated [cs]: only shown on 64-bit if class space is active [linux]: only on Linux [windows]: only on Windows (Vitals version 220600, pid: 18158) Last 60 minutes: -----------------------------------system ----------------------------------- -----------------------------process----------------------------- -----------------------------------jvm------------------------------------ ``` -------------------------------- ### Configure SapMachine in GitHub Actions Source: https://sapmachine.io/docs/github-actions-setup-java Use the actions/setup-java action with the distribution set to 'sapmachine' to specify the Java version in your workflow. ```yaml steps: - uses: actions/setup-java@v5 with: distribution: 'sapmachine' java-version: '25' - run: java -cp java HelloWorldApp ``` -------------------------------- ### Enable Native Memory Tracking summary Source: https://sapmachine.io/docs/vitals Enables NMT with summary level, recommended when using Vitals to track native memory issues. ```bash -XX:NativeMemoryTracking=summary ``` -------------------------------- ### Run latest SapMachine image with podman Source: https://sapmachine.io/docs/docker-images Pulls and runs the latest SapMachine JDK image from GitHub Container Registry, printing the Java version. The image uses the latest Garden Linux version. The --rm flag removes the container after exit. ```bash podman run --rm ghcr.io/sap/sapmachine java -version ``` -------------------------------- ### Example class hierarchy for field expressions Source: https://sapmachine.io/docs/jmc-agent-integration Example class hierarchy used to illustrate how to reference fields in trace expressions. Shows instance fields, static fields, inner classes, and static inner classes. ```java public class Base { String s1 = "baseInstance"; } public class Test extends Base { String s1 = "instance"; static String s2 = "static"; class Inner { private String inner = "inner"; // Method omitted. } static class InnerStatic { public static String inner = "staticInner"; } } ``` -------------------------------- ### Using Java tools with FIPS via JAVA_TOOL_OPTIONS Source: https://sapmachine.io/docs/fips-configuration Sets the JAVA_TOOL_OPTIONS environment variable to pass the same FIPS arguments to JDK tools like keytool and jarsigner. The example shows using keytool after setting the variable. ```bash export JAVA_TOOL_OPTIONS="\ --module-path=/path/to/fips-libs \ -Djava.security.properties=fips.security \ -Dorg.bouncycastle.fips.approved_only=true" keytool ... ``` -------------------------------- ### Launch Java with JDWP agent to include virtual threads Source: https://sapmachine.io/docs/essential-information-on-virtual-threads Use this command to enable debugging of virtual threads by passing the 'includevirtualthreads=y' option to the JDWP agent. This is necessary because virtual threads are hidden by default during debugging. ```bash java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n,includevirtualthreads=y Example.java ``` -------------------------------- ### OpenJDK version output Source: https://sapmachine.io/docs/features Shows the output of `java -version` for a standard OpenJDK build, for comparison with the SapMachine output. ```bash $ ./jdk-25-openjdk/bin/java -version openjdk version "25.0.1" 2025-10-21 OpenJDK Runtime Environment (build 25.0.1+8) OpenJDK 64-Bit Server VM (build 25.0.1+8, mixed mode, sharing) ``` -------------------------------- ### Typical malloc-trace dump output Source: https://sapmachine.io/docs/malloc-trace Shows a sample dump output from the malloc-trace feature. The first line indicates the stack collection mechanism, the second line indicates whether all allocations or only currently allocated memory is included. Stack entries show size, percentage, and allocation count, followed by stack frames with program counter, method name, offset, and library. The summary section provides totals and timing. ```text Stacks were collected via the fallback mechanism. Contains every allocation done since enabling. Stack 1 of 5593: 202,475,760 (193 M, 6.51 %) bytes, 736 (0.03 %) allocations [0x00007f6e0b5e2264] malloc+71 in libmallochooks.so [0x00007f6e09d7d10f] os::malloc(unsigned long, MEMFLAGS, NativeCallStack const&)+153 in libjvm.so [0x00007f6e092728ce] Chunk::operator new(unsigned long, AllocFailStrategy::AllocFailEnum, unsigned long)+400 in libjvm.so [0x00007f6e092731f6] Arena::grow(unsigned long, AllocFailStrategy::AllocFailEnum)+72 in libjvm.so ... Printed 10 stacks Total unique stacks: 5,593 Total allocated bytes: 3,110,684,597 (2.9 G) Total allocation count: 2,236,965 Total printed bytes: 498,194,930 (475 M, 16.0 %) Total printed count: 2,777 (0.12 %) Dumping done in 0.076 s (0.000 s of that locked) ``` -------------------------------- ### Run multiple jcmd commands and heap dump with high memory report Source: https://sapmachine.io/docs/high-memory-reports Enable the high memory report, redirect reports to himem-reports, and run VM.info, VM.flags -all, and GC.heap_dump via jcmd. The report is written to ./himem-reports/sapmachine_himemalert_pid_.log, and each jcmd output is saved as a separate file in the same directory. ```bash java -XX:+HiMemReport -XX:HiMemReportDir=himem-reports '-XX:HiMemReportExec=VM.info;VM.flags -all;GC.heap_dump' ``` -------------------------------- ### Run headless JRE SapMachine image with podman Source: https://sapmachine.io/docs/docker-images Runs a headless JRE variant of SapMachine 25, which is smaller and better suited for backend business applications. The headless variant omits libraries for graphics and sound. ```bash podman run --rm ghcr.io/sap/sapmachine:25-jre-headless java -version ``` -------------------------------- ### Configure SapMachine JRE in manifest.yml Source: https://sapmachine.io/docs/cloud-foundry-buildpacks Declares the JBP_CONFIG_COMPONENTS environment variable in the application's manifest file to use the SapMachine JRE. ```yaml env: JBP_CONFIG_COMPONENTS: '{jres: ["JavaBuildpack::Jre::SapMachineJRE"]}' ``` -------------------------------- ### Trace method parameters with entry Source: https://sapmachine.io/docs/jmc-agent-integration Add a entry to trace method arguments. Each uses an index attribute (0 for the first parameter) and requires a unique and a non-empty . The optional transforms the traced object; a parameter can be traced multiple times with different converters. ```xml parm1 Should not be empty! param2 Should not be empty! java.util.Arrays.toString()V ``` -------------------------------- ### Run latest LTS SapMachine image with podman Source: https://sapmachine.io/docs/docker-images Runs the latest LTS SapMachine release (currently SapMachine 25) on the latest Garden Linux version. Useful when a short-term OpenJDK release is not desired. ```bash podman run --rm ghcr.io/sap/sapmachine:lts java -version ``` -------------------------------- ### System property differences between SapMachine and OpenJDK Source: https://sapmachine.io/docs/features Shows the differences in Java system properties between SapMachine and OpenJDK. Lines prefixed with '-' are OpenJDK values, lines with '+' are SapMachine values. Note the version suffix '-LTS' and SAP vendor information. ```diff - java.runtime.version = 25.0.1+8 + java.runtime.version = 25.0.1+8-LTS - java.vendor = Oracle Corporation - java.vendor.url = https://java.oracle.com/ - java.vendor.url.bug = https://bugreport.java.com/bugreport/ + java.vendor = SAP SE + java.vendor.url = https://sapmachine.io/ + java.vendor.url.bug = https://github.com/SAP/SapMachine/issues/new + java.vendor.version = SapMachine - java.vm.vendor = Oracle Corporation - java.vm.version = 25.0.1+8 + java.vm.vendor = SAP SE + java.vm.version = 25.0.1+8-LTS ```