Files
horizon-airdef/docs/process-memory.md
T
Ludovic Marie 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 <noreply@anthropic.com>
2026-10-13 14:16:55 +02:00

54 lines
3.0 KiB
Markdown

# 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](profiling.md) 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.