Skip to content

gap CLI heap still grows during a klona run after #61 (87 to 821 MB after GC; unattributed) #80

Open

Description

@KyleAMathews

Summary

On the klona four-file suite (295 mutants, 2 contexts, seed 20261112), the gap CLI's child heap still grows during a run, after the retention fixes in #61. Heap after a forced GC, sampled every 2 s in the check child, went from about 87 MB at the start to about 217 MB in the middle and about 821 MB near the end. The run passes at a 1024 MB cap (child peak 930 MB) and completes at 1536 MB (child peak 985 MB). Main (before #61) fails at 2048 MB with a heap-limit fatal.

The growth is not attributed. The retention counters that #61 checks (Vitest's filesMap, pathsSet, idMap, the Vite copy nodes, the cold store, the stale context totals) stay at zero after each batch, so the remaining growth is in something those counters do not measure.

Measurement

Commit: 2b7efe6 on fix/gap-cli-retention (#61). Probe: the heap sampler preload (--expose-gc, forced GC every 2 s, main thread of the check child only).

# heap after GC, first / middle / last samples
cd <checkout of 2b7efe6>/packages/oracles/oracle-gaps
SAMPLE_FILE=/tmp/heap.jsonl node --expose-gc --import ./probe-gc.mjs ./index.mjs \
  --package <klona> --source src/index.js,src/lite.js,src/full.js,src/json.js \
  --seed 20261112 --contexts 2 --mutants <mutants dir> --out <out>

# child peak heap, no probe, cap at 1024 and 1536 MB
node --max-old-space-size=1024 --import ./peak.mjs ./index.mjs <same args>
node --max-old-space-size=1536 --import ./peak.mjs ./index.mjs <same args>

probe-gc.mjs samples process.memoryUsage().heapUsed after globalThis.gc() every 2 s, in the child only (ORACLE_GAPS_GROUP set). peak.mjs samples v8.getHeapStatistics().used_heap_size every 250 ms and prints the peak at exit.

Numbers, from the local runs against 67f057d/59363c8 code:

  • heap after GC: 87 MB (first sample), 217 MB (middle), 821 MB (last sample before exit);
  • 1024 MB cap: exit 0, child peak 930 MB;
  • 1536 MB cap: exit 0, child peak 985 MB;
  • default 2048 MB heap on main (affeb1a): heap-limit fatal, done error ... ran out of memory.

What is ruled out

  • Vitest state entries of retired copies (filesMap, pathsSet, idMap): 0 after each batch.
  • Vite module nodes of retired copies: 0 after each batch.
  • Vite nodes of non-copy files: at most one per file (the query-stripped check in fix(oracle-gaps): retire a batch's copies from Vitest's state #61).
  • The cold run's store (memoryStore): keeps nothing.
  • Vite's transform text, measured as a size on ce6c93d: flat.

What is not known

  • Which structure holds the second-half growth (from 217 to 821 MB). A late heap snapshot, taken near 700 MB, is the next step; its retainer path is not yet checked.
  • Whether the growth follows klona's per-file working set (later files have more mutants and larger tests) rather than residue.

Limits

This issue is about measured heap growth, not a claimed leak. The measurements are from one suite on one machine, under varying load.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions