Files
logan 611a1a5952 docs: client-perf analysis, bench harness and work journal
Everything the next agent needs to run the Phase 2 optimisation loop on a
machine that can launch the client:

- analysis/client-perf/: LEVERS (ranked levers + corrections), BENCH-MATRIX
  (world, scenes, config IDs, blocks B0-B14 with decision rules),
  PLAYER-TUNING, SPAWN-TUNING, research briefs, the jar scanner and its
  output, observed default configs, and proposed-configs/ (build.py
  generates tiers and bench variants and fails on unknown keys;
  apply_variant.py applies a variant and merges options.txt).
- analysis/client-perf/bench/onion-bench/: bench-world datapack (scene
  teleports, Create grid, mob pen, sound storm, 120 s teleport tour).
- analysis/audit/: the static recipe/dependency audit, including gen_fixes.py,
  which generates the shipped Paxi datapack and was never tracked.
- phase0/: per-machine measurement harness (Steam Deck, 7700K/1060,
  6700K/1080 Ti).
- .pi/journal.md: running work log; read it first.

All of it is packwizignored, so nothing here ships to players.
2026-10-14 18:15:32 -04:00

29 KiB
Raw Permalink Blame History

Research: JVM, launcher, OS & driver levers — Onion MC client (NeoForge 1.21.1, Java 21, ~212 mods, Distant Horizons mandatory)

Summary

For a DH-mandatory 200+ mod NeoForge 1.21.1 client, the single biggest platform lever is getting off stock G1 GC (Distant Horizons itself warns about it) onto either Generational ZGC (-XX:+UseZGC -XX:+ZGenerational on JDK 21) or Shenandoah, with heap sized to real headroom (5–6 GB on the 16 GB Deck and the 8 GB-free Linux box, 6–8 GB on the 32 GB Windows box) — oversizing costs more than it buys. Most OS/driver levers are small but cheap: mesa_glthread=true + gamemoderun on the Steam Deck, explicit __GL_THREADED_OPTIMIZATIONS=0 on Linux NVIDIA (Sodium already sets it in source), and NVCP "Prefer maximum performance" on Windows. GraalVM is a benchmark-first experiment only: GraalVM for JDK 21 does not support Generational ZGC and real-world NeoForge 1.21.1 miscompiles exist.


Findings

1. The GC baseline: G1 + why DH complains about it

  • NeoForge 1.21.1 requires Java 21, so GC options are: G1 (default), Parallel (default for server-class? no—G1 default since JDK 9), Generational ZGC, Shenandoah. NeoForge docs (DOCUMENTED).
  • Vanilla ships its own G1 tuning in the client JSON: -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M. Widely quoted from Mojang's version JSON. Minecraft Forum (COMMUNITY, corroborated across 2 threads).
  • Distant Horizons logs at startup: [Render thread/WARN]: Distant Horizons: G1 Garbage collector detected. This can cause FPS stuttering. It's recommended to use a concurrent garbage collector like ZGC (Java 21+) or Shenandoah (Java 8 through 17) for a smoother experience. DH is closed-source; exact wording verified from two independent log excerpts. Minecraft Forum log, New Eden modpack page quoting the warning (DOCUMENTED — it is DH's own runtime warning). Newer DH writes it to the log only instead of an on-screen alert Reddit r/ModdedMinecraft (COMMUNITY). Mechanism is consistent with DH's large LOD allocations → G1 old-gen/mixed pauses = visible stutters (INFERENCE from the warning text + DH's memory behavior).
  • Practical note: on Java 21, -XX:+UseZGC alone selects the legacy non-generational ZGC. Generational ZGC (what you want, and what "Java 21+" implies) needs -XX:+UseZGC -XX:+ZGenerational. Generational mode is only the default on JDK 23+ (JEP 474); non-gen was removed in JDK 24 (JEP 490). OpenJDK ZGC wiki, JEP 474 (VERIFIED).

2. G1 tuned (Aikar-style) vs client

  • Aikar's flags were tuned for Paper servers with large heaps (MaxGCPauseMillis=200, G1NewSizePercent=30…). aikar.co via brucethemoose Benchmark.py (DOCUMENTED origin, COMMUNITY applicability).
  • brucethemoose (benchmarked repo, most credible MC flags source): Aikar's high G1NewSizePercent effectively clamps MaxGCPauseMillis, producing long stutters on some clients; clients also fill old gen far slower than a busy server. He ships a client-flavored G1 set: -XX:+UseG1GC -XX:MaxGCPauseMillis=37 -XX:G1HeapRegionSize=16M -XX:G1NewSizePercent=23 -XX:G1ReservePercent=20 -XX:G1MixedGCCountTarget=3 -XX:G1HeapWastePercent=20 -XX:InitiatingHeapOccupancyPercent=10 -XX:G1RSetUpdatingPauseTimePercent=0 -XX:MaxTenuringThreshold=1 -XX:GCTimeRatio=99 … README (DOCUMENTED, benchmarked; Java-17-era repo — revalidate on 21).
  • Expectation: tuned G1 remains the best default on 4C/8T CPUs with tight RAM (P0, P2). It has no concurrent-cycle CPU tax like ZGC/Shenandoah. (INFERENCE from brucethemoose's guidance "G1GC on servers/clients with less RAM and fewer cores".)

3. Generational ZGC on JDK 21

  • Flags for this pack on JDK 21: -XX:+UseZGC -XX:+ZGenerational -Xmx<N>G (+ optionally -XX:SoftMaxHeapSize, -XX:ConcGCThreads). OpenJDK ZGC wiki (VERIFIED).
  • Sizing rule from the ZGC docs: heap must hold live-set plus headroom for allocations while a cycle runs; "in general, the more memory you give to ZGC the better", balanced against waste; SoftMaxHeapSize lets you cap heuristic target below Xmx. This makes ZGC a poor fit for P2 (only ~8 GB free RAM total) and marginal on the Deck's shared 16 GB. (VERIFIED docs + INFERENCE for fleet.)
  • ZGC pauses are <1 ms regardless of heap, but it costs throughput: brucethemoose measured "a significant client FPS hit" from ZGC on an 8C/16T laptop, and notes ZGC wants more RAM and a raised ConcGCThreads cap (default = logical cores/4; he suggests 2 on 4-thread CPUs). README (DOCUMENTED/COMMUNITY benchmark).
  • DH's warning explicitly blesses ZGC as the primary fix; the DH community answer is always -XX:+UseZGC on Java 21 r/MinecraftHelp NeoForge 1.21.1 thread (COMMUNITY).
  • GraalVM for JDK 21 does not support Generational ZGC ("The following JDK 21 features are not available: JEP 439 Generational ZGC"). So GenZGC ⇒ a plain OpenJDK distro (Temurin et al.), not GraalVM 21. GraalVM JDK 21 release notes (VERIFIED).

4. Shenandoah

  • Not in Oracle JDK; available in Temurin/OpenJDK-based builds "from version 11 onward". Red Hat Temurin docs; not every build ships it — verify with java -XX:+UseShenandoahGC -version Stack Overflow (DOCUMENTED + caveat).
  • brucethemoose's benchmarked verdict: "I recommend Shenandoah on clients"; flags -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1; it dislikes AllocatePrefetchStyle=3; mode/heuristic knobs changed little in his tests. README (DOCUMENTED).
  • Like ZGC it is concurrent, so it eats background CPU on 4C/8T — cheap stutter fix, small FPS tax. (INFERENCE.)

5. Heap sizing for a 200+ mod pack, and the cost of oversizing

  • Prism's own wiki: "MORE RAM ALLOCATED DOESN'T MEAN BETTER PERFORMANCE! … a huge heap makes each garbage collection pause longer, which shows up in game as a stutter." Prism Java settings wiki (DOCUMENTED).
  • brucethemoose: "Allocating too much memory can break gc or just slow Minecraft down, even if you have plenty to spare… allocate only as much as it needs (usually less than 8G)"; set -Xms = -Xmx except on low-RAM systems where Xms should stay below Xmx. README (DOCUMENTED).
  • For this pack: DH's LOD cache, Alex's Caves/Mowzie/Geckolib models and 212 mods plausibly put live-set near 3–5 GB with LODs loaded (INFERENCE — must be measured with Spark/F3). Recommended: P0 5–6 GB, P1 6–8 GB, P2 5 GB max (P2 has ~8 GB free for the whole OS+game). Oversizing harms: longer/less frequent G1 pauses, more RSS stolen from OS/page cache (fatal on 8 GB), ZGC cycles sweeping more memory. (INFERENCE, consistent with both sources above.)

6. -XX:+AlwaysPreTouch and Transparent Huge Pages (Linux)

  • ZGC docs: if low latency is the goal, run Xms=Xmx and use -XX:+AlwaysPreTouch to page memory in before the app starts, avoiding commit/uncommit latency; uncommit can hurt latency. (VERIFIED: ZGC wiki.)
  • THP: -XX:+UseLargePages -XX:+UseTransparentHugePages issues madvise(MADV_HUGEPAGE); requires kernel THP set to madvise in /sys/kernel/mm/transparent_hugepage/enabled (and, for ZGC only, shmem_enabled=advise). Some distros force always/never — check sysfs before benchmarking. (VERIFIED: ZGC wiki.)
  • brucethemoose: large pages "improve performance of Minecraft servers and clients"; on Windows they silently fail without admin/SeLockMemoryPrivilege — on Linux prefer UseTransparentHugePages. (DOCUMENTED: same README.)
  • Cost: slower startup (pre-touch of full heap) and, with THP, potential memory bloat — risky on the 8 GB P2. Use on P1/P0, skip or test carefully on P2. (INFERENCE.)

7. GraalVM CE/EE (Oracle GraalVM) vs Temurin

  • Since the "GraalVM for JDK 21" rebrand there is GraalVM Community Edition (free) and Oracle GraalVM; CE for JDK 21 exists as a full distribution. GraalVM JDK 21 notes (VERIFIED). Note brucethemoose's README is older (recommends "EE 22.x", Java 17) — treat his EE claims as dated but directionally useful.
  • Claims: client FPS gains are modest; chunk-gen/server workloads up to +20% on GraalVM EE. (DOCUMENTED-era 17: README.)
  • Constraints: must use G1 with his Graal flags; GraalVM (of his era) doesn't work with ZGC/Shenandoah — and GraalVM 21 verifiably lacks GenZGC (see §3). (DOCUMENTED both.)
  • Compatibility risk is real on 1.21.1: a dedicated fix repo exists because "Integrated Scripting 1.0.22" crashes on GraalVM JDK 21 + NeoForge 1.21.1 jan-guenter/integratedscripting-graalfix; players report packs failing on GraalVM Java 21 r/feedthebeast (COMMUNITY). With Flywheel 1.0.6 + Veil/Lodestone + Sable/Aeronautics JIT-heavy stacks in this pack, GraalVM is a trial, never the fleet baseline. (INFERENCE.)
  • Obydux's "Minecraft-GraalVM-Flags" is server startup flags for GraalVM EE Java 17 — not applicable to a 1.21.1 client; dropped. Obydux repo.

8. Prism Launcher settings (applies to P0 flatpak and P2)

  • Memory: per-instance Settings → Java → memory box (Xms/Xmx). Prism warns against over-allocation (see §5). Java settings wiki (DOCUMENTED).
  • Java path / JVM args: same Java page — set the Temurin/GraalVM bin/java path and paste JVM arguments. (DOCUMENTED: same page.)
  • Wrapper command: "Wrapper command allows launching using an extra wrapper program (like 'optirun' on Linux)" — this is where gamemoderun goes (Settings → Custom Commands). Custom commands wiki (DOCUMENTED).
  • Environment variables: Prism passes env vars to the java runtime (instance-level). Env vars wiki (DOCUMENTED). Use for mesa_glthread=true, __GL_THREADED_OPTIMIZATIONS=0, vblank_mode=0 etc.
  • Flatpak Prism on the Deck: official install is via their own flatpak repo Prism Steam Deck download; gamemode from inside a flatpak goes through the xdg-desktop-portal GameMode interface (proxies to Feral's daemon with PID mapping/permission checks) portal docs; some flatpaks need flatpak override --talk-name=com.feralinteractive.GameMode for direct D-Bus access example (DOCUMENTED + COMMUNITY).

9. Linux driver/OS levers

  • mesa_glthread: moves GL dispatch to a second thread inside Mesa. radeonsi (which is what Minecraft's OpenGL actually uses on the Deck's Van Gogh APU — RADV is Vulkan and irrelevant here) enables glthread by default since Mesa 22.3; Mesa has also shipped a driconf default for the official Minecraft launcher app since 22.0 — a Prism-launched java process should not be assumed to match those overrides, so set mesa_glthread=true explicitly. Phoronix, PCGamingWiki, MangoHud issue #676 (VERIFIED driver behavior; explicit-set recommendation INFERENCE). Glthread is "a big help to CPU-bound games" — i.e., exactly the Deck's 4-core Zen2 profile. (Phoronix, VERIFIED quote.)
  • NVIDIA proprietary: Sodium 0.8.x/0.6.x sets __GL_THREADED_OPTIMIZATIONS=0 itself on Linux right before GLFW window creation (Libc.setEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", "0") in NvidiaWorkarounds), because threaded optimization causes stalls with Sodium. NvidiaWorkarounds.java (1.21.1/stable) (VERIFIED). Setting it also in Prism env vars is harmless belt-and-braces.
  • gamemode: gamemoderun as Prism wrapper; requests CPU governor + GPU perf level. Feral GameMode / Prism wiki (DOCUMENTED, see §8).
  • Optional: run java at raised priority (renice post-launch; negative nice needs root) — brucethemoose. (DOCUMENTED: README.)

10. Windows (P1) NVIDIA control panel

  • Threaded optimization is effectively not user-controllable for Minecraft: Sodium's author (jellysquid3): the NVIDIA driver "forcefully enables Threaded Optimizations regardless of the control panel settings" because it hardcodes Minecraft detection for all javaw.exe processes. sodium#2061 (VERIFIED, maintainer statement).
  • What Sodium does on Windows instead: spoofs the process command line to net.caffeinemc.sodium / net.minecraft.client.main.Main / (keeps the driver's "good" Minecraft heuristics), then enables GL_DEBUG_OUTPUT_SYNCHRONOUS (KHR_debug) at context creation, which forces the driver to disable threaded command submission. It also detects the broken driver range x.y.15.2647–3622 (526.47 → before 536.23). NvidiaWorkarounds.java, sodium#1486 referenced in source (VERIFIED).
  • NVCP Power management mode → Prefer maximum performance remains a legitimate per-app setting for stabilizing clocks; community standard advice for MC. Minecraft Forum thread on threaded optimization/NVCP, r/feedthebeast NVCP report (COMMUNITY). Note P1 is VRAM-bound (1060 6GB): platform levers help pacing, not the VRAM wall (INFERENCE).

11. Steam Deck (P0) specifics

  • Install Prism via its official flatpak repo; add Prism (or flatpak run org.prismlauncher.PrismLauncher --launch <Instance> desktop entry) as a non-Steam-game so it launches in Game Mode under gamescope (SteamOS's compositor — no extra gamescope config needed at 1280×800 native). Prism Steam Deck page, RetroDECK wiki example with --launch, GamingOnLinux guide (DOCUMENTED + COMMUNITY).
  • UMA frame buffer (VRAM) is 1 GB reserved by default; BIOS allows 4 GB. With DH + shaderpacks + 212 mods on an 8CU iGPU, raising it to 4 GB is a common stability/smoothness tweak (2560×1600 shared-memory reads dominate on Deck). Windows Central how-to, PiMyLifeUp (COMMUNITY).
  • TDP cap (e.g., 8–10 W) stabilizes clocks → steadier frame pacing on battery; standard Deck practice. (COMMUNITY.)
  • GC choice on 4C/8T Zen2 with 16 GB shared RAM: tuned G1 or Shenandoah; avoid ZGC (concurrent-cycle CPU tax + heap headroom taken from the iGPU's shared pool). (INFERENCE from §2–§5.)

12. Sodium's "NO_ERROR_CONTEXT" workaround — what it actually means

  • Sodium's options include "Use No-Error Context" (sodium.options.use_no_error_context, tooltip: "Creates the OpenGL context without error checking") — i.e., Sodium requests a KHR_no_error GL context by default to shave per-call driver error-checking overhead. (VERIFIED from Sodium's own lang strings: sodium#3407.)
  • When the installed driver can't provide that, Sodium logs Sodium has applied one or more workarounds …: [NVIDIA_THREADED_OPTIMIZATIONS_BROKEN, NO_ERROR_CONTEXT_UNSUPPORTED] — NO_ERROR_CONTEXT_UNSUPPORTED simply means the no-error-context optimization was disabled and a normal error-checking context is used; "not necessarily an issue, but it may result in certain features or optimizations being disabled." sodium#2961 log excerpt (VERIFIED).
  • User-facing takeaway: don't try to "fix" this warning; it's informational. Performance impact on supported drivers is small. (INFERENCE.)

Lever Recommended value P0 Deck (Zen2/16GB shared) P1 Win i7-7700K/1060 6GB P2 Linux i7-6700K/1080 Ti, 8GB free Expected impact Risk Confidence
GC engine P0/P2: Shenandoah (-XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000) or tuned G1; P1: Generational ZGC (-XX:+UseZGC -XX:+ZGenerational) tuned G1 or Shenandoah GenZGC (32 GB RAM makes headroom free) tuned G1 or Shenandoah (not ZGC: RAM+CPU poor fit) High (removes DH-flagged G1 stutters) Low (config-only) Med-High
G1 tuning (if G1) brucethemoose client set: MaxGCPauseMillis=37, G1NewSizePercent=23, G1HeapRegionSize=16M, G1MixedGCCountTarget=3, G1HeapWastePercent=20, IHOP=10, MaxTenuringThreshold=1 yes fallback if GenZGC regresses yes Med (1% lows) Low Med
Heap size P0: 5–6 GB · P1: 6–8 GB · P2: 5 GB (Xmx=Xms except P2 low-RAM) 5–6 GB 6–8 GB 5 GB, Xms<Xmx High on P0/P2 (OOM/stutter), Med on P1 Low Med-High
-XX:+AlwaysPreTouch on with Xms=Xmx optional (slower boot from eMMC) yes skip (RAM-tight) Low-Med (pacing consistency) Low Med
THP -XX:+UseLargePages -XX:+UseTransparentHugePages with THP=madvise in sysfs (ZGC also needs shmem_enabled=advise) test only n/a (Windows: large pages need admin — skip) test only (watch RSS bloat) Low-Med Low-Med Low-Med
JVM distro Temurin 21 baseline; GraalVM CE 21 as P1/P2 experiment (G1 only — no GenZGC on GraalVM 21) Temurin Temurin → GraalVM trial Temurin → GraalVM trial (biggest CPU upside here) Low-Med (Med upside on P2 CPU-bound scenes) Med (mod miscompiles; e.g. Integrated Scripting fix repo) Med
Prism wrapper gamemoderun in Custom Commands → wrapper yes n/a yes Low-Med Low High (mechanism), Med (gain)
Prism env vars mesa_glthread=true (P0); __GL_THREADED_OPTIMIZATIONS=0 (P2) yes n/a yes (Sodium also sets it; harmless) Low-Med (P0 CPU-bound GL) Low Med-High
Mesa driver note MC on Deck uses radeonsi (GL), not RADV; glthread default-on since Mesa 22.3 — still set env var for java informational n/a n/a (NVIDIA proprietary has own path) — — High
Windows NVCP Power management: Prefer maximum performance; leave Threaded Optimization alone (driver ignores it for MC; Sodium's GL_DEBUG_OUTPUT_SYNCHRONOUS handles it) n/a yes n/a Low (P1 is VRAM-bound) Low Med
Steam Deck BIOS UMA frame buffer 1 GB → 4 GB; cap TDP ~8–10 W yes n/a n/a Low-Med (stutter/stability) Low-Med (BIOS fiddling) Low-Med
Sodium no-error context leave "Use No-Error Context" enabled; ignore NO_ERROR_CONTEXT_UNSUPPORTED log line leave leave leave ~0 (informational) none High

Sources

Kept

Dropped

  • Obydux/Minecraft-GraalVM-Flags — server startup flags, GraalVM EE Java 17 era; wrong target (client, Java 21).
  • fumora.net GraalVM vs OpenJDK "benchmarks" — third-party, server-plugin workload, methodology unclear.
  • DriverEasy/SystWeak "fix stutter" pages — SEO content, low value.
  • Most Reddit threads kept only as corroboration, not as primary claims (DH warning wording, GraalVM pack failures).

Gaps

  • No credible client-side G1-vs-GenZGC-vs-Shenandoah benchmark for 200+ mod NeoForge 1.21.1 with DH was found; brucethemoose's data is 1.20-era Java 17 and DH's warning is the only pack-specific signal. Must A/B locally (see below).
  • Whether Shenandoah is present in current Temurin 21 Windows x64 builds was not definitively confirmed (Red Hat doc implies yes; some historic Temurin builds lacked it) — verify with java -XX:+UseShenandoahGC -version per machine.
  • SteamOS 3.x current THP sysfs defaults (transparent_hugepage/enabled, shmem_enabled) not verified remotely — check on device.
  • Whether any mod in this pack (AllTheLeaks 1.1.13, DH 3.3.2) calls System.gc() such that -XX:+DisableExplicitGC would be counterproductive — not verified.
  • Sodium 0.8.13-for-1.21.1 is a 2026 backport; exact workaround-list parity with mainline 0.8.x assumed (INFERENCE from 0.8.12 changelog "Improvements for hardware and mod compatibility").

Top levers (ranked)

  1. Move off stock G1 per DH's warning — P1: Generational ZGC; P0/P2: Shenandoah or client-tuned G1. Expected impact High (1% lows / hitching with DH LOD streams). All machines. Risk: low (launcher config). Confidence: Med-High.
  2. Heap sizing discipline (P0 5–6 GB, P1 6–8 GB, P2 5 GB; Xms=Xmx except P2). Impact High on P0/P2, Med on P1. Risk low. Confidence Med-High.
  3. mesa_glthread=true + gamemoderun on the Deck (explicit env var; glthread default-on only for driver/launcher overrides, not necessarily java). Impact Med (CPU-bound GL dispatch on 4 cores). Risk low. Confidence Med.
  4. GraalVM CE 21 trial on P2 (and P1) — G1-only, keep Temurin fallback. Impact Med (CPU-bound chunk/scene prep). Risk Med (miscompiles; no GenZGC). Confidence Med.
  5. __GL_THREADED_OPTIMIZATIONS=0 env var on P2 (Sodium already sets it — belt-and-braces). Impact Low-Med. Risk none. Confidence High (mechanism), Med (gain).
  6. AlwaysPreTouch (+THP madvise) with Xms=Xmx on P1; test on P0; skip on P2. Impact Low-Med (pacing consistency, slower boot). Risk low-med. Confidence Med.
  7. Deck BIOS UMA 4 GB + TDP cap ~8–10 W. Impact Low-Med (stability/frame pacing with DH+shaders on 8CU). Risk low-med. Confidence Low-Med.
  8. Windows NVCP "Prefer maximum performance" on P1; leave Threaded Optimization untouched (Sodium overrides it in code). Impact Low (VRAM-bound). Risk none. Confidence Med.

Open questions to verify by benchmark

  1. On each machine: G1 client-tuned vs Shenandoah vs GenZGC — 1% lows, 0.1% lows and hitch count during DH LOD streaming + chunk gen (use Spark GC monitor + Sodium 0.8.x FPS percentiles).
  2. P1: does GenZGC at 6–8 GB show longer average frame times (concurrent CPU tax) than tuned G1 on the 7700K?
  3. P2: at 5 GB heap with server view-distance 8 + DH, does live-set actually fit (Spark gcmonitor / allocation-rate), or is Shenandoah/G1 forced to over-collect?
  4. Does -XX:+DisableExplicitGC change behavior of DH 3.3.2 / AllTheLeaks 1.1.13 in this pack (explicit-GC dependence)?
  5. GraalVM CE 21: does the full pack (Flywheel 1.0.6, Veil/Lodestone, Sable 2.0.5, Aeronautics 1.3.2, SSRD) survive a 30-min play session without miscompile crashes, and net FPS on P2?
  6. Deck: mesa_glthread=true on/off — measure avg FPS and 1% lows at 1280×800 with Complementary Reimagined r5.9.3 vs MakeUp Ultra Fast 9.5f; also confirm current SteamOS Mesa version's glthread default for a Prism-launched java process.
  7. Deck: UMA 1 GB → 4 GB — measurable reduction in texture-streaming hitches with DH + shaders?
  8. THP madvise on P2 (and shmem_enabled if ZGC tested): THP on/off delta on frame pacing and RSS.
  9. Windows P1: with Sodium active (GL_DEBUG_OUTPUT_SYNCHRONOUS path), any measurable difference from NVCP Threaded Optimization settings at all? (Expect none — confirm.)
  10. Xms=Xmx + AlwaysPreTouch on the Deck: startup time penalty vs frame-pacing benefit.