From 9bd3a98363381ddd843c75985a16380c4c07a64b Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 10 Jul 2026 14:24:30 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20close=20#193=20(OOM=20=E2=80=94=20Opaci?= =?UTF-8?q?ties=20leak,=20measurement-verified)=20+=20file=20#194?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #193 FIXED (119a2326), verified by before/after dotnet-counters on the same 6-min churny roam: LOH 1.1→6.1 GB climbing (leaked) vs 0.24→0.64 GB then FLAT (fixed); no crash. #194 filed: WbDrawDispatcher._groups never pruned (LOW, bounded, not a crash risk) — surfaced during the #193 heap analysis. Co-Authored-By: Claude Opus 4.8 --- docs/ISSUES.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/ISSUES.md b/docs/ISSUES.md index d31fc14b..151c3681 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -48,11 +48,19 @@ Copy this block when adding a new issue: ## #166 — Port the portal String-table lookup for WeenieError / UseDone text ## #191 — Tapping W (brief forward press) glides forward without playing the step animation -## #193 — Client OOMs after extended play (~50 min); cause uncharacterized +## #194 — WbDrawDispatcher._groups is never pruned (minor) -**Status:** OPEN — filed 2026-07-10. `post-M2` (stability, not on the M2 critical path; do not chase mid-M2). -**Severity:** MEDIUM→HIGH (crashes the client after extended sessions; eventual ship blocker, tolerable for short dev-iteration loops today). -**Component:** unknown — memory growth somewhere in the render/streaming/entity path during continuous play. +**Status:** OPEN — filed 2026-07-10. `post-M2`, LOW priority. Surfaced during the #193 heap analysis. +**Severity:** LOW — bounded, not a crash risk (unlike #193 which was the real OOM). +**Component:** render — `WbDrawDispatcher._groups` (`Dictionary`, WbDrawDispatcher.cs:236). + +`_groups` accumulates one `InstanceGroup` per distinct `GroupKey` (mesh + texture + translucency + cull combo) ever seen, and is never pruned when the entities/landblocks that created a group unload. After the #193 fix, groups for unloaded content are reset to empty each frame (cheap: the object + five empty `List` ≈ a couple hundred bytes) but the dictionary entry lingers. Bounded by the number of distinct render-group combos in the world (hundreds–low thousands), so total cost is sub-MB — plateaus, does not grow like a leak. Fix if convenient: drop groups whose instance count stayed 0 for N frames, or clear entries on landblock unload. Not urgent. + +## #193 — Client OOMs after extended play (~50 min) — FIXED + +**Status:** ✅ FIXED + measurement-verified 2026-07-10 (`119a2326`). Root cause: `WbDrawDispatcher.InstanceGroup.Opacities` (a `List` added by #188) was appended one float per drawn instance per frame but never cleared — the per-frame reset loop (WbDrawDispatcher.cs:959) cleared its four sibling parallel lists but not Opacities. `List` capacity-doubling → ~128 MB/512 MB LOH `float[]` → ~1 GB/min → OOM after ~50 min. Fix: extract the reset into `InstanceGroup.ClearPerInstanceData()` clearing ALL FIVE parallel lists (so a future 6th can't drift out); TDD `InstanceGroupClearTests`. **Before/after (same 6-min churny roam, dotnet-counters):** working set 1.6→7.6 GB (leaked) vs 0.75→1.36 GB (fixed); LOH 1.1→6.1 GB (climbing) vs 0.24→0.64 GB then FLAT (240→607→641→641→641). No crash on the fixed build. (Move to Recently closed on next tidy.) +**Severity:** was MEDIUM→HIGH (crashed after extended sessions). RESOLVED. +**Component:** render — `WbDrawDispatcher` per-frame instance-group reset. **Observed 2026-07-10 (two crashes in one evening, both Release build):** - Crash 1: `dotnet : Out of memory.` after an extended dev-UI session; smoke plugin `saw 37085 entities total` at teardown.