[GR-71288] Conditionally reduce JFR global buffer defaults to lower footprint #12502
+16
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
JfrRecorderThreadis 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
JfrRecorderThreadto write in-flight data to disk more frequently. However, I believe it is uncommon for users to set non-default JFR flushing intervals.