Files
horizon/docs/process-memory.md
T
Ludovic MarieandClaude Opus 5.5 8cdec2c8d9 Tidy the repository now that parity is reached: launcher-first README, docs index, research leftovers removed
Removed (each unreferenced by code, workflows, tests or living docs; no harness
dependency record names any of them, and parity.py --list still finds all 281):
- 22 one-off write-ups of the Java-pack experiments in docs/: adaptive-terrain,
  client-graphics-smoke, compact-headers, core-performance, culling-empty,
  culling-rays, debounce-queue, dispatch-retry, foreground-first,
  graphics-api-comparison, heap-budget, mac-first-test, optimization-plan,
  playable-validation, quad-reuse, server-graphics-context, shader-world-smoke,
  terrain-measurements, terrain-position, terrain-read-wait, tick-membership,
  worker-pacing. Their findings are folded into one paragraph of java-packs.md.
- 24 benchmarks/ observation dumps only those write-ups linked (client graphics,
  culling, queues, heap, Mac Vulkan, shader worlds, software identity, and the
  unlinked rust-core, rust-worldgen-2026-10-05, rust-native-client and
  rust-cuboid-model-decoding runs), plus 12 unlinked files inside kept
  report folders. The scoped-parity reports the living docs cite stay.
- debug/: one server log from a chunk investigation.
- The manual macos-shader-research and macos-vulkan-research workflows.
- tools/logs/latest.log, an empty log committed by accident (now ignored).

Kept: research-lock.json (parity.py, packaging, the launcher and datafix read
it), the Java-pack how-tos (vulkan, collectors, profiling, process-memory,
tick-state) and tools/test_client_graphics.py (ci.yml runs it).

README: leads with what Horizon is and "Download the launcher" (the
launcher-v* releases; the launcher updates itself), then build from source
for developers. Direct game downloads and PLAY.txt steps for players are gone;
the launcher has its own section with two screenshots. The roadmap merges the
known differences, the final checks and the plans after parity, under the
"Roadmap" heading the launcher's What's next page reads. The parity table and
its 100%-of-what-the-harnesses-compare note are unchanged.

docs/README.md indexes what remains: build and run, parity (status and
workflow), world generation, world data and simulation, the old Java track.
Links to the removed pages and README anchors are fixed.

packaging/PLAY.txt now speaks to players who came through the launcher and
points anyone with a bare archive to it, keeping the manual steps short.

The launcher's README link points at main instead of the launcher branch.
.gitignore: tools/logs/ and .DS_Store. No code behaviour changes; the compiler
and clippy flag no unused code and the tree has no stale TODOs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 14:16:55 +02:00

3.0 KiB

Measuring resident process memory

Horizon 0.6.0 records process RSS alongside JVM heap and nonheap pools. RSS counts resident pages belonging to the Minecraft process, including native allocations and mapped pages. It helps detect cases where reducing heap use merely moves memory elsewhere. It is not unique physical-memory ownership or a complete accounting of GPU allocations, shared pages, compressed memory, swap, or Apple Silicon unified memory. Do not add heap to RSS: heap pages can already be included in it.

Minecraft 26.3 already ships OSHI 6.9.0 and JNA on both client and server. The original mod uses those dependencies without embedding them. Native reader initialization and refresh happen on a low-priority daemon thread, never on the render or server-tick thread. One reader serves overlapping frame and tick recordings. Reads run about once per second only while recordings are active; the scheduler stops polling when the last recording finishes. Ordinary gameplay without a benchmark performs no resident-memory reads.

Reports include these optional schema-1 fields:

Field Meaning
process_rss_peak_sampled_bytes Largest successful resident-memory sample during this recording
process_rss_last_sampled_bytes Last successful sample, which can precede recording completion
process_rss_samples Number of successful samples delivered to this recording
process_rss_sample_interval_ms Requested 1,000 ms interval; reads can take longer
process_rss_last_sample_age_ms Time from the last successful sample to report completion

Unsupported or failed reads leave these fields absent if no sample succeeded; zero is not used as a substitute. Frames and ticks continue recording. A read that completes after a recording finishes is ignored. Sampled peaks can miss brief spikes, and the initial read can be delayed by native-library startup.

The offline viewer compares RSS separately from heap/nonheap and warns about stale resident samples. Keep recording duration, workload and warm-up matched when comparing peaks. Process CPU counters cover the whole process over the recording wall time, including native work and the integrated server; they do not identify which thread or mod caused CPU use.

gc_time_ms sums collector MXBean collection-time counters. With concurrent collectors these can include cycle duration and overlapping phases; it is not a direct stop-the-world pause measurement. The viewer calls it collection time. Use JFR pause events when investigating GC-induced stalls.

A three-pair heap experiment compared 3 GiB and 1.5 GiB maximum heaps with the same core stack. It recorded variable RSS savings, nearly unchanged average FPS and increased GC accounting; playable defaults stayed unchanged.

The native-read test exercises the real library, overlapping recordings, background execution, idle cancellation and unavailable-reader behavior on the build platform. This validates measurement availability, not an FPS or RAM optimization result.