#!/usr/bin/env bash # Scoped Values (JEP 506, final since JDK 25) vs ThreadLocal. StructuredTaskScope (JEP 505) is # still PREVIEW on JDK 25 -- every file here that touches it needs --enable-preview --release 25. # ./scripts/scoped-values.sh -> docs/output/99-basics.txt 99-inheritance.txt # 99-memory-heap-delta.txt 99-histogram-scopedvalue.txt # 99-histogram-threadlocal.txt set -uo pipefail source "$(dirname "$0")/env.sh" S="$ROOT/scoped-values/src"; B="$ROOT/build/scoped-values"; rm -rf "$B"; mkdir -p "$B" # ScopedValuesBasics.java needs no preview flag (JEP 506 is final); the other three touch # StructuredTaskScope and need --enable-preview. "$JDK25/bin/javac" -d "$B" "$S/Check.java" "$S/ScopedValuesBasics.java" 2>&1 | grep -v -E '^(Note:|$)' || true "$JDK25/bin/javac" --enable-preview --release 25 -Xlint:-preview -d "$B" "$S"/*.java 2>&1 | grep -v -E '^(Note:|$)' || true { echo "\$ java ScopedValuesBasics (JDK 25, no preview flag -- JEP 506 is final)" "$JDK25/bin/java" -cp "$B" ScopedValuesBasics 2>&1; echo "exit=${PIPESTATUS[0]}" } > "$OUT/99-basics.txt" 2>&1 { echo "\$ java --enable-preview InheritanceRequiresStructuredTaskScope (JDK 25)" "$JDK25/bin/java" --enable-preview -cp "$B" InheritanceRequiresStructuredTaskScope 2>&1; echo "exit=${PIPESTATUS[0]}" } > "$OUT/99-inheritance.txt" 2>&1 { echo "\$ java --enable-preview -Xmx6g ScopedValueVsThreadLocalMemory 500000 (JDK 25)" "$JDK25/bin/java" --enable-preview -Xmx6g -cp "$B" ScopedValueVsThreadLocalMemory 500000 2>&1; echo "exit=${PIPESTATUS[0]}" } > "$OUT/99-memory-heap-delta.txt" 2>&1 # Precise version: park N=100000 subtasks holding 5 bound values each, then ask the JVM itself # (jcmd GC.class_histogram) how many objects of each class actually exist while they're all alive. histogram() { local mode="$1" outfile="$2" rm -f "$B/probe.log" "$JDK25/bin/java" --enable-preview -Xmx3g -cp "$B" MemoryFootprintProbe "$mode" 100000 > "$B/probe.log" 2>&1 & local pid=$! for _ in $(seq 1 60); do grep -q "READY $mode" "$B/probe.log" 2>/dev/null && break; sleep 1; done { echo "\$ jcmd GC.class_histogram (100000 subtasks parked, mode=$mode, JDK 25)" "$JDK25/bin/jcmd" "$pid" GC.class_histogram 2>&1 \ | grep -E 'ThreadLocal|VirtualThread |SubtaskImpl|Carrier|ScopedValue|StackChunk|^Total' \ | grep -v CarrierThread } > "$OUT/$outfile" 2>&1 kill -9 "$pid" 2>/dev/null wait "$pid" 2>/dev/null } histogram sv 99-histogram-scopedvalue.txt histogram tl 99-histogram-threadlocal.txt scrub() { sed -i -E "s#$ROOT##g" "$@"; } scrub "$OUT"/99-*.txt echo "wrote $OUT/99-*.txt"