# Memory-return experiment: supporting data

Measured on 2026-10-30: CPython 3.11.2 / Linux 6.12 / aarch64 / glibc 2.36 / 4 KiB pages / default pymalloc.

`phases.csv` contains observations at each processing stage. `main` is the uninstrumented experiment: three fresh processes (`rep`) per case, two cycles (`cycle`) each. `traced` is a separate tracemalloc diagnostic: one fresh process and one cycle per case. Do not pool RSS from these two stages.

Cases: `large` is one 32 MiB bytearray; `small` is 80,000 bytearray(256) objects; `sparse` retains one in every 64 of the same buffers; `cycles` is 80,000 self-referencing Nodes, each with a bytearray(256). Object and list bookkeeping takes additional space.

Phases: `baseline` follows full GC and trim before allocation; `allocated` follows allocation; `dropped` follows removal of outer references; `idle_3s` follows about three seconds of waiting; `forced_gc` follows manual full GC; `anchors_released` follows clearing retained references and another GC; `trimmed` follows malloc_trim(0).

`rss_mib` is current RSS, and `rss_delta_mib` is its difference from that cycle's baseline. `pss_mib` and `anonymous_mib` are PSS and Anonymous. These come from smaps_rollup. One MiB is 1,048,576 bytes. `elapsed_s` is seconds from the observation start within the process. `gc_wall_ms` and `gc_cpu_ms` are manual collection wall time and process CPU time; they are zero for other phases. An empty `collected` field means the collection count was not recorded in this column for that phase. GC also runs before baseline and anchors_released.

`sample_alive` counts living objects in a sample of 32 weak references to cyclic Nodes; it is not a total live-object count. `gc_events` counts completed collections observed after installing the measurement callback, including preparatory collections. `traced_delta_mib` is the increase in Python-traced allocations above the cycle baseline. `tracemalloc_bookkeeping_mib` is tracing bookkeeping memory. Both are zero in `main`, where tracing is disabled. They do not measure all native allocations.

`timeline.csv` contains `main` samples taken approximately every 200 ms. Its `elapsed_s` starts at each process's first baseline, unlike the origin in phases.csv. RSS, PSS, Anonymous, and cgroup memory.current are separate columns; cgroup charges are not the same metric as RSS.

Worker limits: 0.25 core, 128 MiB, no swap allowance. Full GC and trim run before each cycle; the cyclic case also runs a collection while references remain live. Do not generalize to long-term idle behavior or application pause times. Graph bars span the minimum and maximum of six observations from three processes × two cycles, not a confidence interval.

These files omit raw internal logs, connection targets, host names, PIDs, service names, and internal paths.
