DEV Community

SickleFire
SickleFire

Posted on

M-vis v0.5.0-rc1 update

[0.5.0-rc1] - 2026-07-6
Added

  • CI/CD Mode: Full programmatic integration layer with JSON/CSV export, differential leak detection (--diff-only), configurable sampling, and growth rate monitoring.
  • Enhanced TUI: keyboard-driven process selection, quick action buttons.
  • Improved Leak Detection: Better Linux heap walk via /proc/maps, optimized memory diff algorithms for large heaps.

Catching Memory Leaks in CI with mvis v0.5.0-rc1

mvis now ships as a reusable GitHub Action, so you can drop heap monitoring and leak detection straight into your existing workflow — no manual binary download, no custom scripts. This post walks through setting it up using the v0.5.0-rc1 pre-release.

What the action does

Under the hood, the action:

  1. Downloads the right mvis binary for the runner's OS and architecture (Linux, Windows, or macOS — Intel or Apple Silicon).
  2. Builds a mvis ci command from your inputs.
  3. Runs it against a PID, a fuzzy process name, or a command you want it to spawn and watch.

Basic usage

- name: Run mvis memory audit
  uses: SickleFire/m-vis@v0.5.0-rc1
  with:
    version: v0.5.0-rc1
    spawn: ./target/release/my_app
    max-memory: 512
    duration: 60
Enter fullscreen mode Exit fullscreen mode

This spawns my_app, watches it for 60 seconds, and fails the step if it ever exceeds 512 MB RSS.

On Windows, max-memory currently depends on the underlying heap-walk succeeding. If the walk itself errors out for some reason, mvis can still complete the step rather than failing loud — worth keeping in mind if a step passes suspiciously easily.

Choosing a target

You need exactly one of these three inputs:

Input Use case
spawn You want mvis to launch and own the process. Must be the last thing you configure — anything after it in the composite action's internal command line gets treated as arguments to your spawned command, not to mvis.
pid You already have a running process (e.g. started in an earlier step) and just want to attach.
process-name Fuzzy-match against running processes by name — handy when the PID isn't known ahead of time.

Note: spawn currently needs a path with a separator in it — ./my_app, build/my_app.exe — even when the binary sits right in the working directory. A bare filename like spawn: my_app.exe fails with program not found, because the path-resolution logic doesn't fall back to checking the current directory the way a shell normally would. Always prefix with ./ (or the equivalent relative path) to be safe.

# Attach to an already-running process by PID
- name: Start server
  run: ./server & echo "pid=$!" >> "$GITHUB_OUTPUT"
  id: server

- name: Monitor it
  uses: SickleFire/m-vis@v0.5.0-rc1
  with:
    version: v0.5.0-rc1
    pid: ${{ steps.server.outputs.pid }}
    duration: 120
    max-memory: 1024
Enter fullscreen mode Exit fullscreen mode

Monitoring flags

  • max-memory — fail the step if RSS crosses this many MB.
  • leak-check — compares a baseline snapshot against the end state and fails if net-retained memory looks like a leak rather than expected steady-state growth.
  • duration — how long to watch before mvis exits (in seconds). If omitted, mvis watches until the target process exits on its own.

You can combine max-memory and leak-check in the same run — mvis will fail the step on whichever condition trips first.

A note on macOS

The macOS binaries are ad-hoc signed with an entitlements file so mvis can inspect another process's memory. This is still being hardened for CI use — if you're running the smoke-test / action-triggered flow on macos-latest and see it hang rather than pass or fail cleanly, that's a known area under active investigation rather than a config mistake on your end. Linux and Windows runners aren't affected.

Full example: fail PRs on memory regressions

name: Memory check
on: [pull_request]

jobs:
  memory-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build app
        run: cargo build --release

      - name: Run mvis memory audit
        uses: SickleFire/m-vis@v0.5.0-rc1
        with:
          version: v0.5.0-rc1
          spawn: ./target/release/my_app
          max-memory: 256
          leak-check: true
          duration: 45
Enter fullscreen mode Exit fullscreen mode

That's it — one job, no custom scripting, catching memory regressions before they merge.


Author:

  • SickleFire

See M-vis, leave a star, a bug report and PR is always welcomed!

Top comments (0)