Add jfr-demo: JFR + Mission Control profiling of a live Spring Boot app
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.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
Same workload (40 rounds of GET /api/lock/contend?workers=2&holdMillis=12, each
|
||||
round producing exactly one waiter blocked for ~12 ms) run against three
|
||||
ISOLATED recordings, one at a time, so each sees its own settings only.
|
||||
|
||||
--- settings=default (jdk.JavaMonitorEnter threshold = 20 ms) ---
|
||||
$ jcmd 5287 JFR.start name=soloDefault settings=default
|
||||
$ for i in $(seq 1 40); do curl -s "localhost:8080/api/lock/contend?workers=2&holdMillis=12" -o /dev/null; done
|
||||
$ jcmd 5287 JFR.stop name=soloDefault filename=recordings/solo-default.jfr
|
||||
$ jfr print --events jdk.JavaMonitorEnter recordings/solo-default.jfr | grep -c duration
|
||||
0
|
||||
|
||||
--- settings=profile (jdk.JavaMonitorEnter threshold = 10 ms) ---
|
||||
$ jcmd 5287 JFR.start name=soloProfile settings=profile
|
||||
$ for i in $(seq 1 40); do curl -s "localhost:8080/api/lock/contend?workers=2&holdMillis=12" -o /dev/null; done
|
||||
$ jcmd 5287 JFR.stop name=soloProfile filename=recordings/solo-profile.jfr
|
||||
$ jfr print --events jdk.JavaMonitorEnter recordings/solo-profile.jfr | grep -c duration
|
||||
40
|
||||
$ jfr print --events jdk.JavaMonitorEnter recordings/solo-profile.jfr | grep duration | sort | uniq -c
|
||||
1 duration = 10.2 ms
|
||||
13 duration = 12.1 ms
|
||||
11 duration = 12.2 ms
|
||||
9 duration = 12.3 ms
|
||||
1 duration = 12.4 ms
|
||||
1 duration = 12.6 ms
|
||||
1 duration = 13.6 ms
|
||||
1 duration = 14.2 ms
|
||||
1 duration = 14.9 ms
|
||||
1 duration = 30.3 ms
|
||||
|
||||
--- settings=default again, this time with a 35 ms hold (above BOTH thresholds) ---
|
||||
$ jcmd 5287 JFR.start name=soloDefault2 settings=default
|
||||
$ for i in $(seq 1 10); do curl -s "localhost:8080/api/lock/contend?workers=2&holdMillis=35" -o /dev/null; done
|
||||
$ jcmd 5287 JFR.stop name=soloDefault2 filename=recordings/solo-default-longhold.jfr
|
||||
$ jfr print --events jdk.JavaMonitorEnter recordings/solo-default-longhold.jfr | grep -c duration
|
||||
10
|
||||
|
||||
Conclusion, with real counts to back it: a monitor hold of ~12 ms is invisible to
|
||||
"settings=default" (0 of 40 waits captured) but fully visible to "settings=profile"
|
||||
(40 of 40). The same default recording catches every wait once the hold is raised
|
||||
to 35 ms (10 of 10). This is `jdk.JavaMonitorEnter`'s threshold doing exactly what
|
||||
the shipped default.jfc / profile.jfc files say (20 ms vs 10 ms) -- see
|
||||
docs/output/08-concurrent-recordings-shared-threshold.txt for what happens to this
|
||||
picture the moment a SECOND recording with a lower threshold is also running.
|
||||
Reference in New Issue
Block a user