Reproduces the pinning JEP 491 did not fix (native JNI frames) with a real native library, alongside the monitor case it did fix. Covers the jdk.VirtualThreadPinned JFR event, reading pinned vs unmounted virtual threads from a jcmd Thread.dump_to_file, the measured throughput cost on a capped carrier pool, and a bounded-executor pattern to contain the blast radius. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01FhzLY5p6okFva3qsnsRyvM
113 lines
5.6 KiB
Bash
Executable File
113 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Regenerates every file in output/. Requires:
|
|
# - JDK25_HOME pointing at a JDK 24+ install (this repo used Temurin 25.0.4.1+1)
|
|
# - JDK21_HOME pointing at a pre-JDK-24 install (this repo used OpenJDK 21.0.10), for the
|
|
# before/after comparisons against JEP 491
|
|
# - gcc on PATH (builds the JNI native library)
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
: "${JDK25_HOME:?Set JDK25_HOME to a JDK 24+ install}"
|
|
: "${JDK21_HOME:?Set JDK21_HOME to a pre-JDK-24 install}"
|
|
|
|
JAVA_HOME="$JDK21_HOME" ./scripts/build-native.sh
|
|
|
|
mkdir -p target/classes target/classes-21
|
|
"$JDK25_HOME/bin/javac" --release 25 -d target/classes $(find src/main/java -name "*.java")
|
|
"$JDK21_HOME/bin/javac" --release 21 -d target/classes-21 $(find src/main/java -name "*.java")
|
|
|
|
NATLIB=target/native
|
|
|
|
echo "--- 01: monitor pinning, JDK21 vs JDK25 (JEP 491) ---"
|
|
{
|
|
echo '$ java -Djdk.tracePinnedThreads=full MonitorPinningDemo (pre-JDK-24 runtime)'
|
|
echo ""
|
|
"$JDK21_HOME/bin/java" -Djdk.tracePinnedThreads=full -cp target/classes-21 \
|
|
com.ankurm.vtpinning.MonitorPinningDemo 2>&1 | grep -v "Picked up"
|
|
echo ""
|
|
echo '$ java -Djdk.tracePinnedThreads=full MonitorPinningDemo (JDK 24+ runtime)'
|
|
echo ""
|
|
"$JDK25_HOME/bin/java" -Djdk.tracePinnedThreads=full -cp target/classes \
|
|
com.ankurm.vtpinning.MonitorPinningDemo 2>&1 | grep -v "Picked up"
|
|
} > output/01-monitor-pinning-jdk21-vs-jdk25.txt
|
|
|
|
echo "--- 02: native pinning, JDK21 vs JDK25 (still real on both) ---"
|
|
{
|
|
echo '$ java -Djdk.tracePinnedThreads=full NativePinningDemo (pre-JDK-24 runtime)'
|
|
echo ""
|
|
"$JDK21_HOME/bin/java" -Djdk.tracePinnedThreads=full -Djava.library.path=$NATLIB -cp target/classes-21 \
|
|
com.ankurm.vtpinning.NativePinningDemo 2>&1 | grep -v "Picked up"
|
|
echo ""
|
|
echo '$ java -Djdk.tracePinnedThreads=full NativePinningDemo (JDK 24+ runtime - flag is inert)'
|
|
echo ""
|
|
"$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.tracePinnedThreads=full -Djava.library.path=$NATLIB -cp target/classes \
|
|
com.ankurm.vtpinning.NativePinningDemo 2>&1 | grep -v "Picked up\|WARNING"
|
|
} > output/02-native-pinning-jdk21-vs-jdk25.txt
|
|
|
|
echo "--- 03: jdk.VirtualThreadPinned JFR event on JDK25 ---"
|
|
rm -f target/native-pin.jfr
|
|
{
|
|
echo '$ java -XX:StartFlightRecording=...,jdk.VirtualThreadPinned#enabled=true,threshold=0ms NativePinningDemo'
|
|
echo ""
|
|
"$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED \
|
|
"-XX:StartFlightRecording=filename=target/native-pin.jfr,settings=profile,jdk.VirtualThreadPinned#enabled=true,jdk.VirtualThreadPinned#threshold=0ms,jdk.VirtualThreadPinned#stackTrace=true" \
|
|
-Djava.library.path=$NATLIB -cp target/classes com.ankurm.vtpinning.NativePinningDemo 2>&1 \
|
|
| grep -v "Picked up\|WARNING\|jfr,startup\|^\["
|
|
echo ""
|
|
echo '$ jfr print --events jdk.VirtualThreadPinned --stack-depth 10 target/native-pin.jfr'
|
|
echo ""
|
|
"$JDK25_HOME/bin/jfr" print --events jdk.VirtualThreadPinned --stack-depth 10 target/native-pin.jfr 2>&1 | grep -v "Picked up"
|
|
} > output/03-jfr-virtualthreadpinned-event.txt
|
|
|
|
echo "--- 04: jcmd Thread.dump_to_file, pinned vs unpinned virtual thread ---"
|
|
rm -f target/threaddump.json target/threaddump_out.txt
|
|
"$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djava.library.path=$NATLIB -cp target/classes \
|
|
com.ankurm.vtpinning.ThreadDumpPinnedDemo > target/threaddump_out.txt 2>&1 &
|
|
PID=$!
|
|
sleep 1.5
|
|
"$JDK25_HOME/bin/jcmd" "$PID" Thread.dump_to_file -format=json target/threaddump.json > target/jcmd_out.txt 2>&1
|
|
wait $PID
|
|
{
|
|
echo '$ java ThreadDumpPinnedDemo &'
|
|
grep -v "Picked up" target/threaddump_out.txt
|
|
echo ""
|
|
echo '$ jcmd <pid> Thread.dump_to_file -format=json threaddump.json (taken mid-flight)'
|
|
grep -v "Picked up" target/jcmd_out.txt
|
|
echo ""
|
|
echo '--- the two virtual thread entries from that dump ---'
|
|
python3 - <<'PYEOF'
|
|
import json
|
|
with open('target/threaddump.json') as f:
|
|
data = json.load(f)
|
|
for c in data['threadDump']['threadContainers']:
|
|
for t in c.get('threads', []):
|
|
if t.get('virtual'):
|
|
print(json.dumps(t, indent=2))
|
|
print()
|
|
PYEOF
|
|
} > output/04-jcmd-thread-dump-pinned-vs-unpinned.txt
|
|
|
|
echo "--- 05: throughput cost of native pinning vs plain blocking (capped carriers) ---"
|
|
{
|
|
echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 PinningThroughputDemo native 4 1000'
|
|
"$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \
|
|
com.ankurm.vtpinning.PinningThroughputDemo native 4 1000 2>&1 | grep -v "Picked up\|WARNING"
|
|
echo ""
|
|
echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 PinningThroughputDemo plain 4 1000'
|
|
"$JDK25_HOME/bin/java" -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \
|
|
com.ankurm.vtpinning.PinningThroughputDemo plain 4 1000 2>&1 | grep -v "Picked up\|WARNING"
|
|
} > output/05-pinning-throughput-cost.txt
|
|
|
|
echo "--- 06: bounding the blast radius with a dedicated executor ---"
|
|
{
|
|
echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 BoundedNativeCallDemo direct'
|
|
"$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \
|
|
com.ankurm.vtpinning.BoundedNativeCallDemo direct 2>&1 | grep -v "Picked up\|WARNING"
|
|
echo ""
|
|
echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 BoundedNativeCallDemo bounded'
|
|
"$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \
|
|
com.ankurm.vtpinning.BoundedNativeCallDemo bounded 2>&1 | grep -v "Picked up\|WARNING"
|
|
} > output/06-bounded-executor-fix.txt
|
|
|
|
echo "Done. See output/."
|