Skip to content

Conversation

@roberttoyonaga
Copy link
Collaborator

@roberttoyonaga roberttoyonaga commented Nov 7, 2025

Summary

This PR reduces the global buffer count and size by 50%, resulting in 2.5 MB of in-flight global storage rather than 10 MB.

Motivation

The JFR global buffers dominate JFR's portion of native memory usage. By default, there are 20 global buffers, each of size 512 KB. In total this is 10 MB. These defaults are obtained from the host JDK at build time.
Native Image executables are often smaller, shorter lived applications. I believe that they will generally emit less events than applications made to run on the JVM. Furthermore, it is more critical for JFR to have lower footprint on Native Image than the JVM. This is because Native Image executables generally have lower RSS than apps running on the JVM, meaning JFR's relative contribution to RSS becomes higher. For these reasons, I think it is worthwhile adjusting the global buffer size and count to be lower if the user has not manually specified their own settings via -XX:FlightRecorderOptions.

Risks

The risk of doing this is that there could be data loss if JFR is not able to persist in-flight data to disk before global buffer capacity runs out. However, I think that this risk is heavily mitigated now that we support JFR flushing (1s intervals by default). As long as the data creation rate is under 2.5 MB/s the risk of data loss will be low. Additionally, whenever the global buffers get too full, the JfrRecorderThread is signaled to persist full buffers to disk. .

I did a quick test using a basic Quarkus getting-started quickstart app. I used Hyperfoil to drive a load of 1000 requests/s for 4s. this resulted in a 873 KB snapshot (event + constant + metadata). That averages out to 218.25 KB/s. Of course, the data generation rate will be heavily dependent on user's specific workloads, but this is an indication that 2.5MB/s is not too unreasonable.

It is possible that the user sets a much longer than default flush interval or disables flushing entirely. This would cause JFR to rely on the JfrRecorderThread to write in-flight data to disk more frequently. However, I believe it is uncommon for users to set non-default JFR flushing intervals.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Nov 7, 2025
@roberttoyonaga roberttoyonaga marked this pull request as ready for review November 7, 2025 21:48
@christianhaeubl christianhaeubl changed the title Conditionally reduce JFR global buffer defaults to lower footprint [GR-71288] Conditionally reduce JFR global buffer defaults to lower footprint Nov 10, 2025
@christianhaeubl christianhaeubl self-assigned this Nov 10, 2025
@christianhaeubl
Copy link
Member

I thought about that a bit and there are a few things that I don't like about the current approach:

  • If a user for example sets globalBufferCount, then globalBufferSize will change to the build-time default as well. I think that behavior would be pretty surprising for a user (e.g., if the user doubles the globalBufferCount, we will suddenly use 4x of the memory).
  • At the moment, we are copying the (potentially modified) build-time values from HotSpot. If JFR is enabled at build-time as well (potentially with custom buffer count/size), this can result in unexpected behavior at run-time.

So, I think we need to set proper default values at build-time to avoid surprises at run-time. I opened https://github.com/oracle/graal/pull/12510/files, please have a look and let me know what you think.

@roberttoyonaga
Copy link
Collaborator Author

Hi @christianhaeubl

That's a good point. If a user becomes accustomed to the new reduced defaults, it might be surprising that multiple values change when the decide to specify any global buffer settings.

Also a good point about inheriting potentially modified settings from JFR at build time.

@christianhaeubl
Copy link
Member

Thanks, #12510 should then also get merged in the next few days.

@roberttoyonaga
Copy link
Collaborator Author

Thank you Christian

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

native-image native-image-jfr OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants