Skip to content

fix(status): keep an emulator's memory in its workspace and let ps finish under load - #1828

Merged
janicduplessis merged 2 commits into
mainfrom
fix/1791-memory-swings
Sep 28, 2026
Merged

janicduplessis merged 2 commits into
mainfrom
fix/1791-memory-swings

Conversation

@janicduplessis

@janicduplessis janicduplessis commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Description

stim status --json reported an idle emulator workspace's memoryMb as 442, 3200 and about 4700 MB a few minutes apart (#1791). Only ~4700 is a real reading (qemu footprint + Metro). The other two are separate failures:

  • 442: the emulator was not charged to its workspace. attributeMachineUsage required android.serial, which comes from the adb lookup. When that lookup misses (always during boot, sometimes under load) the qemu tree lands on an owner with workspace: null. The requirement came in with feat(status): attribute CPU and memory to one owner per process #1586 with no stated reason; the running qemu -avd <name> process already proves the emulator runs.
  • 3200: exactly the estimate (2500 emulator + 700 Metro). Status keeps the estimate whenever the host ps read returns null. On this heavily loaded Mac that ps usually takes 30-80 ms but sometimes stalls for seconds and hit the 5 s timeout; one real status --json came back with machine: null and the workspace at 3200. The footprint helper never stalled.

A dev checkout has one more path to 3200 (dist/stim-footprint.swift missing during a rebuild); published installs never hit it, so it is left alone.

Solution

  • An emulator counts in the workspace that records its AVD whenever its launcher or qemu process runs, whether adb lists it yet or not. A recorded AVD Stim does not own is now attributed too, as booted simulators Stim does not own already are.
  • The host process table ps gets 10 s instead of 5 s, so a stall finishes instead of swapping in a different measure. A retry would run into the same stall.

Trade-off: the host table is read synchronously, so a stalled ps now blocks for up to 10 s instead of 5 s: one status --watch refresh (still under its 15 s interval), the one-shot gc --idle and budget activity reads, and the bare supervisor's idle-stop check, which runs Metro in-process and so pauses it; that check only runs once a workspace is past its idle deadline. The async web-driver ps keeps its 5 s timeout.

Payload meaning and memorySource values are unchanged, so the phone app, Desktop, stim-server and guide need no edits. Summing RSS as a fallback was ruled out: the same qemu's RSS swung 1636-3334 MB in the issue's log while its footprint held at ~4.1-4.3 GB.

Test plan

  • machine-usage.test.ts: new case with an emulator at serial: null, state: 'not-detected'; fails on main, passes here.

  • Real emulator in my own workspace, cycled with stim stop / start / android while sampling status --json from main's build and this branch's at the same moments. The sample where qemu ran but adb did not list it yet:

    main:   memoryMb  380, emulator owner workspace=null (501 MB)
    branch: memoryMb 1109, emulator owner in the workspace (729 MB)
    

    After boot both read the same (~4.9-5.5 GB, Metro bundling included).

  • ps latency with the exact status arguments in a spawnSync loop at load avg ~140-270: p50 73 ms, p99 780 ms, max 2.5 s in 800 runs; one ETIMEDOUT at 5196 ms in another 300; two concurrent runs stalled to 4.1 s together. The helper's max was 51 ms in 800 runs. This branch's status --json runs the unchanged ps arguments against the real tool.

Fixes #1791

@janicduplessis
janicduplessis marked this pull request as ready for review September 28, 2026 21:28
@janicduplessis
janicduplessis merged commit a4fb475 into main Sep 28, 2026
8 checks passed
@janicduplessis
janicduplessis deleted the fix/1791-memory-swings branch September 28, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

status: per-workspace memoryMb swings between 0.4 and 4.7 GB for an unchanged workspace

1 participant