Skip to content

Rock Pi 4 1 GB: residual OOM-restart under sustained mixed-asset rotation (post-#2915) #2916

Description

@vpetersson

After the low-RAM gates in #2915, the Rock Pi 4 1 GB testbed still OOM-restarts under a realistic sustained rotation — less often than before the patch, but still observable.

Repro

5-asset rotation: image, 1080p H.264 video, 1080p HEVC video, light webpage (example.com), heavy webpage (engadget.com). 30s per asset (videos play at their actual ~15s length), ~2 min cycle.

Image 22abfb2-arm64 (worktree of #2915). Single-QWebEngineView mode engaged, 4K gate active, swap fully used at idle.

Timeline

Time Event
0:00 Sampler + rotation started, viewer PID 15213, swap_used ~494 MB
0:00-0:20 viewer_rss oscillating 220-263 MB across cycles, no monotonic climb
~0:22 Sampler gap (system too memory-starved to honour sleep 30 reliably)
~0:35 dmesg: Out of memory: Killed process 14893 (bash) oom_score_adj:1000start_viewer.sh's shell got the OOM kill, container restarted via docker's restart: always
~0:35 Viewer container back up, single-view mode re-engaged

Hypothesis

engadget.com renderer is ~120 MB RSS; HEVC SW decode at 1080p needs another ~50-80 MB working set; AnthiasViewer main process is ~250 MB after warmup. With the kernel + host services + redis + server + celery, the box exceeds total RAM+swap at the worst cycle phase, kernel picks the highest oom_score_adj victim (start_viewer.sh's bash), container restarts.

Possible follow-up mitigations (independent investigations)

  1. Heavyweight-URL gate. Some way to reject URL assets that exceed a measured renderer RSS — first load probe, or operator-set hint. Cleanest UX (matches the 4K codec gate). Hard part: WebEngine RSS isn't trivially predictable from the URL.
  2. Chromium memory caps. QTWEBENGINE_CHROMIUM_FLAGS="--js-flags=--max-old-space-size=128 --memory-pressure-off=false" on low-RAM. Risk: caps V8 heap, which on many sites means breakage.
  3. libavcodec thread count cap. Currently SW decode uses all 6 A72 cores' worth of pipeline; capping to 2 threads would shrink the working-set ring buffer at the cost of slower decode. On a 1 GB box "slower" is fine; "OOM" is not.
  4. mpv/mp4 cache cap. QtMultimedia's ffmpeg backend has a configurable demuxer cache. Default may be too generous.
  5. Disable swap on low-RAM. The current swap-thrash signature (sampler sleep 30 taking 16 minutes) is worse UX than a clean OOM. Without swap, the kernel OOMs faster and the container restarts cleanly.

Acceptance for the follow-up

On the same 5-asset Rock Pi 4 rotation, 4+ hour run completes without container restart. Sampler sleep cadence stays within 10% of nominal.

Out of scope for this issue

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