Custom OrderProcessed event, CPU/allocation/lock workloads, a diagnostic endpoint over the JVM's live FlightRecorder state, a JUnit test using the jdk.jfr.Recording API, and nine captured recordings (flagship, mid-flight snapshot, isolated vs concurrent threshold comparisons, and a real dump+stop duplication bug) with their docs/output/*.txt transcripts.
36 lines
2.2 KiB
Plaintext
36 lines
2.2 KiB
Plaintext
Allocation pressure from three concurrent GET /api/alloc/churn?iterations=400000
|
|
calls, captured by jdk.ObjectAllocationSample in recordings/live-demo.jfr.
|
|
|
|
$ jfr print --events jdk.ObjectAllocationSample recordings/live-demo.jfr | grep objectClass \
|
|
| sed 's/^\s*//' | sort | uniq -c | sort -rn
|
|
|
|
154 objectClass = java.lang.Object[] (classLoader = bootstrap)
|
|
111 objectClass = byte[] (classLoader = bootstrap)
|
|
21 objectClass = java.util.ArrayList (classLoader = bootstrap)
|
|
19 objectClass = java.lang.String (classLoader = bootstrap)
|
|
4 objectClass = java.time.Instant (classLoader = bootstrap)
|
|
2 objectClass = java.io.EOFException (classLoader = bootstrap)
|
|
1 objectClass = java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode (classLoader = bootstrap)
|
|
1 objectClass = java.util.concurrent.ConcurrentHashMap$KeyIterator (classLoader = bootstrap)
|
|
1 objectClass = java.util.LinkedHashMap$Entry (classLoader = bootstrap)
|
|
1 objectClass = java.util.HashSet (classLoader = bootstrap)
|
|
|
|
Top allocating stack frames (--stack-depth 1), same recording:
|
|
|
|
153 java.util.ArrayList.<init>(int) line: 157
|
|
58 java.lang.String.encodeUTF8(byte, byte[], boolean) line: 1305
|
|
49 jdk.internal.misc.Unsafe.allocateUninitializedArray(Class, int) line: 1396
|
|
21 com.ankurm.jfr.service.WorkloadService.churnAllocations(int) line: 55
|
|
18 com.ankurm.jfr.service.WorkloadService.churnAllocations(int) line: 53
|
|
4 java.time.Instant.create(long, int) line: 416
|
|
4 java.nio.HeapByteBuffer.<init>(int, int, MemorySegment) line: 75
|
|
|
|
The two biggest allocators by class (Object[] and byte[]) both trace back to one
|
|
line in WorkloadService.churnAllocations: `new ArrayList<>(bytes.length)` followed
|
|
by boxing each byte into the list. Object[] is the list's own backing array
|
|
(resized as autoboxed Byte objects are added); byte[] is `s.getBytes()`. Total
|
|
events: 317 (jdk.ObjectAllocationSample, throttled to 300/s by the "profile"
|
|
settings used for this recording -- see docs/output/08-concurrent-recordings-
|
|
shared-threshold.txt for why throttle and threshold settings between concurrently
|
|
active recordings interact in a way that is easy to misread).
|