Conversation
19a978f to
878ab16
Compare
fcbcd85 to
3496f10
Compare
3496f10 to
9261d6f
Compare
66940ae to
c9fa930
Compare
7c315a1 to
63d9beb
Compare
defe6aa to
2647565
Compare
|
Hi @babsingh Could you please review the changes, Thanks |
|
Optimize recalibration and integrate JFR standard settings/configuration in separate PRs. |
| J9ArrayClass *arrayClass = (J9ArrayClass *)data->clazz; | ||
| U_8 *classLeafName = J9UTF8_DATA(J9ROMCLASS_CLASSNAME(arrayClass->leafComponentType->romClass)); | ||
| UDATA lenClassLeafName = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(arrayClass->leafComponentType->romClass)); |
There was a problem hiding this comment.
use tabs for indentation to match the coding standard
| MM_ObjectAllocationSamplingInternalEvent *data = | ||
| (MM_ObjectAllocationSamplingInternalEvent *)eventData; | ||
| J9VMThread *currentThread = data->currentThread; | ||
|
|
||
| U_8 *className = J9UTF8_DATA(J9ROMCLASS_CLASSNAME(data->clazz->romClass)); | ||
| UDATA lenClassName = J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(data->clazz->romClass)); |
There was a problem hiding this comment.
these read-only locals be made const: data, className, the name lengths, and arrayClass/classLeafName.
| UDATA newInterval = ((0 != totalBytes) && (0 != lastGCEnd)) | ||
| ? (totalBytes * 1000000 / (elapsedMicros * throttleRate)) | ||
| : J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_INTERVAL; | ||
| if (newInterval < 1024) { | ||
| newInterval = 1024; | ||
| } else if (newInterval > (64 * 1024 * 1024)) { | ||
| newInterval = 64 * 1024 * 1024; | ||
| } |
There was a problem hiding this comment.
macros must be defined for: 1000000, 1024 and 64, as per the coding standard, similar to
#define J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_THROTTLE_RATE 150
#define J9JFR_OBJECT_ALLOCATION_SAMPLE_PROFILING_THROTTLE_RATE 300
| #define J9JFR_GLOBAL_BUFFER_SIZE (10 * J9JFR_THREAD_BUFFER_SIZE) | ||
| #define J9JFR_SAMPLING_RATE 10 | ||
| #define J9JFR_CLASSNAME_BUFFER_SIZE 128 | ||
| #define J9TIME_NANOSECONDS_PER_SECOND (1000000000ULL) |
There was a problem hiding this comment.
this doesn't appear to be used
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_INTERVAL (512 * 1024) /* bytes; same as JVMTI default per JEP 331 */ | ||
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_THROTTLE_RATE 150 /* events per second */ | ||
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_PROFILING_THROTTLE_RATE 300 /* events per second */ |
There was a problem hiding this comment.
inconsistent spacing before the comment
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_INTERVAL (512 * 1024) /* bytes; same as JVMTI default per JEP 331 */ | |
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_THROTTLE_RATE 150 /* events per second */ | |
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_PROFILING_THROTTLE_RATE 300 /* events per second */ | |
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_INTERVAL (512 * 1024) /* bytes; same as JVMTI default per JEP 331 */ | |
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_THROTTLE_RATE 150 /* events per second */ | |
| #define J9JFR_OBJECT_ALLOCATION_SAMPLE_PROFILING_THROTTLE_RATE 300 /* events per second */ |
| J9JFRObjectAllocationSample *jfrEvent = (J9JFRObjectAllocationSample *)reserveBufferWithStackTrace( | ||
| currentThread, currentThread, J9JFR_EVENT_TYPE_OBJECT_ALLOCATION_SAMPLE, sizeof(J9JFRObjectAllocationSample), 0); |
There was a problem hiding this comment.
reserveBufferWithStackTrace() can eventually flush the JFR buffer, where allocateMemFromGlobalBuffer() releases VM access to acquire jfrBufferMutex. Since this callback is running from the allocation hook, can we confirm that it is valid for the subscriber to drop VM access here and that the allocator does not retain any GC sensitive refs across the hook dispatch? If not, this path needs to avoid dropping VM access or protect/update those references.
@gacholio for review
| SystemGCID = 36, | ||
| YoungGarbageCollectionID = 38, | ||
| OldGarbageCollectionID = 39, | ||
| ObjectAllocationSampleID = 83, /* jdk.ObjectAllocationSample -- must match JFR metadata blob */ |
There was a problem hiding this comment.
does this also work with JFRv2?
There was a problem hiding this comment.
for Java17 also JfrObjectAllocationSampleEvent = 83, but need to update for Java 25 JfrObjectAllocationSampleEvent = 91
There was a problem hiding this comment.
Is this consistent (or correctly inconsistent, I suppose) with the RI? I suppose we only really care about LTS versions.
There was a problem hiding this comment.
for Java17 also JfrObjectAllocationSampleEvent = 83, but need to update for Java 25 JfrObjectAllocationSampleEvent = 91
In V1 it will be the same for all Java versions. Don't worry about V2 for now @thallium is working on a change that will use the generated IDs in V2.
Also, the comment /* jdk.ObjectAllocationSample -- must match... is not needed as it applies the same to all Ids in the enum.
There was a problem hiding this comment.
Here's the PR for using generated IDs in JFR v2: #24839
| Trc_VM_jfrObjectAllocationSample_indexableObject(currentThread, | ||
| lenClassName, | ||
| className, | ||
| lenClassLeafName, | ||
| classLeafName, | ||
| data->weight, | ||
| data->objectSize); | ||
| } else { | ||
| Trc_VM_jfrObjectAllocationSample(currentThread, | ||
| lenClassName, | ||
| className, |
There was a problem hiding this comment.
arguments should start on a new line
| jfrEvent->objectClass = data->clazz; | ||
| jfrEvent->weight = data->weight; |
There was a problem hiding this comment.
| jfrEvent->objectClass = data->clazz; | |
| jfrEvent->weight = data->weight; | |
| jfrEvent->objectClass = data->clazz; | |
| jfrEvent->weight = data->weight; |
| } | ||
|
|
||
| /* enable JFRObjectAllocationSample */ | ||
| vm->jfrState.objectAllocationSampleThrottleRate = J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_THROTTLE_RATE; |
There was a problem hiding this comment.
| vm->jfrState.objectAllocationSampleThrottleRate = J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_THROTTLE_RATE; | |
| vm->jfrState.objectAllocationSampleThrottleRate = J9JFR_OBJECT_ALLOCATION_SAMPLE_DEFAULT_THROTTLE_RATE; |
8dc6291 to
8d23c13
Compare
| static constexpr int NETWORK_UTILIZATION_EVENT_SIZE = (4 * sizeof(U_64)) + sizeof(U_32); | ||
| static constexpr int DATA_LOSS_EVENT_SIZE = sizeof(U_8) + LEB128_32_SIZE + (3 * LEB128_64_SIZE); | ||
| static constexpr int THREAD_ALLOCATION_STATISTICS_EVENT_SIZE = sizeof(U_8) + LEB128_32_SIZE + (3 * LEB128_64_SIZE); | ||
| /* OBJECT_ALLOCATION_SAMPLE_EVENT_SIZE: eventSize(LEB128_64) + eventType(LEB128_32) + ticks(LEB128_64) + eventThread(LEB128_64) + stackTrace(LEB128_32) + objectClass(LEB128_32) + weight(LEB128_64) */ |
| I_64 ticks; | ||
| U_64 eventThreadIndex; | ||
| U_32 stackTraceIndex; | ||
| U_32 objectClassIndex; /**< class constant-pool index for the allocated object class */ |
6696a8e to
4f90688
Compare
Base on JFR event specification (from [SAP JFR Events 17](https://sap.github.io/jfrevents/17.html#objectallocationsample)): - 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(). - 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. - 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). Signed-off-by: lhu <linhu@ca.ibm.com>
4f90688 to
76316ae
Compare
Base on JFR event specification (from SAP JFR Events
17):
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().
JFR specifies
ObjectAllocationSamplethrottling 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
Nevents/second are emitted. JVM startup uses a reasonable defaultbyte interval 512KB. new objectAllocationSampleThrottleRate (throttle
value (events/s)) in vm->jfrState.
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).
#depends on: eclipse-omr/omr#8407
#depends on: #24774
#relate to: #24778
#fix: #24213
Signed-off-by: lhu linhu@ca.ibm.com