Skip to content

[Native Image] JFR native memory usage increases steadilyΒ #12253

@joggeli34

Description

@joggeli34

Describe the Issue

We use the build flag --enable-monitoring=jfr,nmt as we like to use pyroscope for profiling. This works in general well, but we see a constant increase of memory that is not on the heap.

On the left, the container memory. On the right the heap:
Image

With the native memory tracking, we see that the JFR native memory is big and it seems to be growing the longer we let the application run:

Total
    (reserved=33774140KB, committed=762642KB)
    (malloc=219708KB, count=24817)
    (peak malloc=288450KB, count at peak=57367)
    (mmap: reserved=33554432KB, committed=542933KB)
    (mmap: peak reserved=33554432KB, peak committed=753190KB)
Java Heap
    (reserved=33461440KB, committed=450453KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=33461440KB, committed=450453KB)
    (mmap: peak reserved=33461440KB, peak committed=660710KB)
JFR
    (reserved=198613KB, committed=198613KB)
    (malloc=198613KB, count=24706)
    (peak malloc=232462KB, count at peak=62502)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)

We use the pyroscope-java, which creates a lot of JFR recordings with this code:
https://github.com/grafana/pyroscope-java/blob/main/agent/src/main/java/io/pyroscope/javaagent/JFRJDKProfilerDelegate.java

Otherwise we use default setting for the JFR, so we add no additional settings as start parameter.
By my understanding, the JFR default settings should use a lot less memory and should not lead to constant growing memory. Or is there a setting I missed to limit that?

Using the latest version of GraalVM can resolve many issues.

GraalVM Version

java 25 2025-09-16 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 25+37.1 (build 25+37-LTS-jvmci-b01)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 25+37.1 (build 25+37-LTS-jvmci-b01, mixed mode, sharing)

Operating System and Version

docker image: quay.io/quarkus/ubi9-quarkus-micro-image:2.0

Troubleshooting Confirmation

Run Command

./application -XX:+ExitOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -Xmx1500m -Xmn256m -XX:MaxDirectMemorySize=128m -XX:+PrintNMTStatistics -XX:MaxHeapFree=128m -XX:MaxRAM=1800m

Expected Behavior

We expect the JFR native memory to stay limited on a small size (some megabytes)

Actual Behavior

The JFR native memory increases the longer the application is run

Steps to Reproduce

In our application, it is always the case when enabling pyroscope with jfr profiling

Additional Context

No response

Run-Time Log Output and Error Messages

Native memory log:

Total
    (reserved=33774140KB, committed=762642KB)
    (malloc=219708KB, count=24817)
    (peak malloc=288450KB, count at peak=57367)
    (mmap: reserved=33554432KB, committed=542933KB)
    (mmap: peak reserved=33554432KB, peak committed=753190KB)
Compiler
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Code
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
GC
    (reserved=3KB, committed=3KB)
    (malloc=3KB, count=66)
    (peak malloc=6KB, count at peak=113)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Heap Dump
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Image Heap
    (reserved=92992KB, committed=92480KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=92992KB, committed=92480KB)
    (mmap: peak reserved=92992KB, peak committed=92480KB)
Java Heap
    (reserved=33461440KB, committed=450453KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=33461440KB, committed=450453KB)
    (mmap: peak reserved=33461440KB, peak committed=660710KB)
JFR
    (reserved=198613KB, committed=198613KB)
    (malloc=198613KB, count=24706)
    (peak malloc=232462KB, count at peak=62502)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
JNI
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=1)
    (peak malloc=0KB, count at peak=1)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
jvmstat
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
JVMTI
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Native Memory Tracking
    (reserved=387KB, committed=387KB)
    (malloc=387KB, count=24817)
    (peak malloc=1257KB, count at peak=80474)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
PGO
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Serviceability)
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=0KB, count at peak=0)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Threading
    (reserved=2KB, committed=2KB)
    (malloc=2KB, count=20)
    (peak malloc=15KB, count at peak=117)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Unsafe
    (reserved=20701KB, committed=20701KB)
    (malloc=20701KB, count=24)
    (peak malloc=82734KB, count at peak=57)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)
Internal
    (reserved=0KB, committed=0KB)
    (malloc=0KB, count=0)
    (peak malloc=1KB, count at peak=1)
    (mmap: reserved=0KB, committed=0KB)
    (mmap: peak reserved=0KB, peak committed=0KB)

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions