Issues / #2934

#2934 [Bug]: Long sessions: parking evicts every conversation and still refuses (freed memory stays in glibc's heap)

open · @alfre2v · 0 Kommentare · Auf GitHub

BenchmarksSetup & installServer & APINVIDIA / CUDAModels & quantsLinux

Beschreibung


### What happened

After a server has been busy for a while, an agent's main conversation gets **read again from scratch** after a subagent switch, although parking is on and the budget isn't full. On my box, a 214K-token conversation took 90 s to re-read instead of 11 s. A freshly started server doesn't show it; it appears once many conversations have been parked and evicted.

The engine log shows it like this:
```
strata serve: conversation cache: skip parking (physical RAM admission; need 1483 MiB plus 3072 MiB floor, 4501 MiB available, source meminfo; evicted 3, 0 still parked)
strata serve: prompt 214234 tokens = 0 reused + 214234 read in 90425 ms (2369.2 tok/s), ...
```
`evicted 3, 0 still parked`: the RAM check threw away every parked conversation and still refused. A milder form appears too: `evicted 3 parked conversations to admit this snapshot`, where 1 would have been enough. Another conversation then loses its context for nothing.

**Cause:**
- parked conversations are 16 MiB `std::vector` segments (`conversation_buffer.hpp`);
- glibc's mmap threshold is dynamic: once a large mapped block has been freed, later 16 MiB segments come from the heap, and freeing them doesn't give the memory back to the OS;
- the RAM check reads `MemAvailable`, so evicting a conversation never shows up as free RAM.

The comments at `generate.cpp:8322-8324` and `conversation_cache.hpp:279-281` (v0.1.44.1) assume the opposite.

**Fix:** proposed in #2253 (`malloc_trim` in the RAM check). Independent test results on this box are in [my comment on #2253](https://github.com/Niko1221/Strata/pull/2253#issuecomment-6236955827): it fixes the gate in all three runs, with no prefill cost on short prompts.

**Workaround until a fix is released:** add one line to the `env` block of your run config (`strata-<model>.json`; the server passes it to the engine), then restart the server:
```json
"GLIBC_TUNABLES": "glibc.malloc.mmap_threshold=4194304"
```
- 4 MiB or 8 MiB fix it on this box. 16 MiB fixes it only partly; 32 MiB or unset don't.
- Cost here: fresh-prompt reading 4-9% slower at 4K, about 3% at 32K, 2-3% at 120-250K. Decode is unaffected.
- Linux/glibc only. Setup re-runs keep `env` entries.

**To reproduce:** start the server with parking on (here `--conversation-cache-mib 8192 --conversation-cache-slots 4 --conversation-cache-min-free-mib 3072`). Send fresh prompts that park and evict several large conversations (here 32K-250K tokens), then run an agent session where a main conversation grows past about 190K tokens while alternating with subagents. The refusal comes at the main conversation's park. It reproduced on every unpatched run of that sequence.

### Strata version, GPU, OS

0.1.44.1 (`296b59d`, engine built locally with CUDA 13.0) · RTX 3090 24GB, Ryzen 9 3900X, 64 GB RAM · Ubuntu 22.04 (glibc 2.35) · Qwen3.8-Flash-Next IQ3_S, `--max-context 262144 --kv int8 --kv-grow`

### Engine log

The relevant lines are above. The full test data (ladder, soak and engine logs for unpatched, the workaround and #2253) is summarised in [my comment on #2253](https://github.com/Niko1221/Strata/pull/2253#issuecomment-6236955827).

Mehr auf der Site

Links zu Install, Modellen, Releases.