Skip to content

memory: most live Rust heap has no resident owner; swap excluded #2490

Description

@ScriptedAlchemy

Summary

Most of the daemon's live Rust heap has no resident owner, so the resident-memory authority charges a fraction of what it measures. Separately, the admission sample excludes swapped anonymous pages.

Evidence

Operator daemon, beta.59, 12:40 to 13:10 UTC, read-only. Sources: /proc/<pid>/smaps and tracedecay tool status --format json.

Region Resident Swapped
mimalloc arenas (Rust heap) 6.60 GiB 3.64 GiB
glibc arena heaps (C libraries; fixed separately, see the linked PR) 5.54 GiB 3.76 GiB
  • memory.retained_bytes (sum of charged owners): 3,550,304,770
  • memory.resident_bytes: 17,516,769,280
  • VmSwap: 8,387,836 kB. It is not counted in the admission sample (unreclaimable_bytes = RssAnon + RssShmem).
  • 4 registered projects, 1 worktree each. No linked-worktree duplication.

Isolated reproduction. Debug production,hotpath build, MemoryMax=6G, MemorySwapMax=1G. Corpus: depth-1 clone of this repository (5,747 files). Cold index, then settle.

  • Charged owners: graph_catalog 400,257,698 plus graph_engine 665,139,632 (1,065,397,330 total).
  • mimalloc arenas: 2,530 MiB resident plus 478 MiB swapped.
  • mi_collect(true) on all 113 threads (gdb, scratch daemon only) released nothing, so this is live or fragmented heap, not freed-but-retained pages.
  • Symptom: every refresh after a commit is refused: code-index worker resident-memory admission refused: ... observed_rss=3234574336 ... high_watermark=5798205849 requested=4429185024. The index stays warming indefinitely. That matches the operator's tracedecay project, which sat at rebuild_in_flight=true / code_graph_serving=pending for hours.

Expected

Retained Rust state that the daemon holds after a cold index (about 1.5 GB uncharged on this corpus) is registered as a resident owner, so it can be shed or at least attributed. Admission accounting also decides explicitly whether swapped anonymous pages count.

Not done

Attribution of the uncharged Rust heap. The Hotpath alloc lane reports allocated bytes per function, not live retention, so this needs a live-heap profile (for example dhat on a system-allocator build).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions