Skip to content

Implement the JFR ObjectAllocationSample event - step1 - #24609

Open
LinHu2016 wants to merge 4 commits into
eclipse-openj9:masterfrom
LinHu2016:jfrAllocationSampling2
Open

Implement the JFR ObjectAllocationSample event - step1#24609
LinHu2016 wants to merge 4 commits into
eclipse-openj9:masterfrom
LinHu2016:jfrAllocationSampling2

Conversation

@LinHu2016

@LinHu2016 LinHu2016 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Base on JFR event specification (from SAP JFR Events
17
):

  • 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.

#depends on: eclipse-omr/omr#8407
#fix: #24213
Signed-off-by: lhu linhu@ca.ibm.com

@LinHu2016
LinHu2016 force-pushed the jfrAllocationSampling2 branch 2 times, most recently from 19a978f to 878ab16 Compare August 24, 2026 16:03
@tajila
tajila requested review from dmitripivkine and tajila August 25, 2026 15:11
@LinHu2016
LinHu2016 force-pushed the jfrAllocationSampling2 branch 13 times, most recently from fcbcd85 to 3496f10 Compare August 27, 2026 14:13
Signed-off-by: lhu <linhu@ca.ibm.com>
Signed-off-by: lhu <linhu@ca.ibm.com>
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>
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
LinHu2016 force-pushed the jfrAllocationSampling2 branch from 3496f10 to 9261d6f Compare August 28, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JFR: ObjectAllocationSample event

2 participants