Implement the JFR ObjectAllocationSample event - step2 - #24659
Open
LinHu2016 wants to merge 2 commits into
Open
Conversation
LinHu2016
force-pushed
the
jfrAllocationSampling_recalibrateU
branch
from
August 28, 2026 15:44
d170227 to
906d77c
Compare
Base on JFR event specification (from [SAP JFR Events 17](https://sap.github.io/jfrevents/17.html#objectallocationsample)): - Introduce a new GC hook J9HOOK_MM_OBJECT_ALLOCATION_SAMPLING_INTERNAL that is functionally identical to J9HOOK_MM_OBJECT_ALLOCATION_SAMPLING but is designated internal-only (JVM use only, no Java code runs in callbacks). This prevents the hook's registration from disabling JIT OSR safe-point optimization in vmhook.c. - Define the event structure J9JFRObjectAllocationSample in j9nonbuilder.h and J9JFR_EVENT_TYPE_OBJECT_ALLOCATION_SAMPLE id in j9consts.h - Register a JFR-internal callback jfrObjectAllocationSample() on J9HOOK_MM_OBJECT_ALLOCATION_SAMPLING_INTERNAL in startJFRRecording(), implement the callback to write a J9JFRObjectAllocationSample event with a stack trace into the per-thread buffer, and unregister it in stopJFRRecording(). - new jfrObjectSamplingBytesGranularity in GCExtensionBase new _jfrTraceAllocationBytes in EnvironmentBase for tracking and triggering J9JFRObjectAllocationSample event. - JFR specifies `ObjectAllocationSample` throttling in events-per-second (default: 150/s, profiling: 300/s). The GC layer works in bytes. A conversion is needed: from the JVM's current heap allocation rate (bytes/sec), derive a byte-granularity interval such that approximately `N` events/second are emitted. JVM startup uses a reasonable default byte interval 512KB. new objectAllocationSampleThrottleRate (throttle value (events/s)) in vm->jfrState. - New function j9gc_set_jfr_allocation_sampling_interval() to let JFR enable/disable/reconfigure the threshold. - Add a periodic recalibration step in jfrSamplingThreadProc()'s 1-second tick block, Read total bytes allocated since last GC, Compute new byte interval: newInterval = allocatedBytes / (throttleRate * elapsedSinceLastGC). - handle the case JVMTI sampling is also active, arm the TLH top at the nearer of the two next-trigger points so that neither sampler fires late. Signed-off-by: lhu <linhu@ca.ibm.com>
LinHu2016
force-pushed
the
jfrAllocationSampling_recalibrateU
branch
from
August 28, 2026 15:48
906d77c to
a783dde
Compare
The original allocation sample byte interval recalibration was performed in jfrSamplingThreadProc(), which runs every second. It collects totalBytes allocated since the end of the previous GC cycle and divides it by the elapsed time since that GC to calculate the allocation rate. Collecting totalBytes since the previous GC cycle requires acquiring exclusive VM access, which may introduce performance concerns. The recalibration is now performed in jfrRecalibrateObjectAllocationSampleInterval(), which is called at the start of a GC cycle. At this point, flushCachesForGC() has already merged all per-thread allocation statistics into extensions->allocationStats. The allocation rate is calculated using the allocation statistics collected during the interval since the previous GC cycle ended. Based on this rate, the per-thread sampling interval is adjusted to keep the observed event rate close to the configured throttle rate. To avoid frequent small adjustments, a new sampling interval is applied only when it differs from the current interval by more than 5%. Signed-off-by: lhu <linhu@ca.ibm.com>
LinHu2016
force-pushed
the
jfrAllocationSampling_recalibrateU
branch
from
August 28, 2026 17:43
a783dde to
431a7c3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Update the recalibration of the JFR ObjectAllocationSample interval.
The original allocation sample byte interval recalibration was performed
in jfrSamplingThreadProc(), which runs every second. It collects
totalBytes allocated since the end of the previous GC cycle and divides
it by the elapsed time since that GC to calculate the allocation rate.
Collecting totalBytes since the previous GC cycle requires acquiring
exclusive VM access, which may introduce performance concerns.
The recalibration is now performed in
jfrRecalibrateObjectAllocationSampleInterval(), which is called at the
start of a GC cycle. At this point, flushCachesForGC() has already
merged all per-thread allocation statistics into
extensions->allocationStats.
The allocation rate is calculated using the allocation statistics
collected during the interval since the previous GC cycle ended. Based
on this rate, the per-thread sampling interval is adjusted to keep the
observed event rate close to the configured throttle rate.
To avoid frequent small adjustments, a new sampling interval is applied
only when it differs from the current interval by more than 5%.
#depends on #24609
Signed-off-by: lhu linhu@ca.ibm.com