Describe the Bug
Streaming from a virtual headless output leaks VRAM as orphaned DMA-BUFs that
are visible in neither nvidia-smi's process list nor any process's fd table.
The leak accumulates continuously (~1.3 GB/h) while a stream is active, and
survives client disconnect — only restarting Sunshine frees it.
Measured on an RTX 5090 32GB over two sessions:
- ~30 GB VRAM unaccounted for after ~2 days of intermittent streaming
- 24.9 GB leaked after one overnight session; freed instantly by
systemctl --user restart sunshine (24893 → 2723 MiB)
- 1-hour instrumented run: unattributed VRAM grows 1819 → 2570 MiB while
streaming, stays flat after client disconnect, grows again on reconnect
Key observation: leaked buffers match the physical monitor, not the streamed one
/sys/kernel/debug/dma_buf/bufinfo (as root) shows thousands of leaked
buffers with refcount 2 and no attached devices:
size flags mode count exp_name ino name
39321600 00000002 02080007 00000002 drm 00974892 <none>
Attached Devices:
Total 0 devices attached
... (repeated ~800x, plus a second size class)
20971520 00000002 02080007 00000002 drm 00974746 <none>
- 39321600 bytes = exactly 3840×2560×4 → the physical monitor (BenQ RD280U)
- 20971520 bytes = 2048×2560×4 (aligned variant)
- The streamed output is a virtual headless monitor "SUNSHINE" at 1512×982
(output_name = SUNSHINE), i.e. the leaked buffers are the wrong size for
the capture target — they appear to be allocated per capture cycle against
the physical display and never released.
Config
capture = wlr
output_name = SUNSHINE
Hyprland (Wayland). Sunshine uses the zwlr_screencopy_manager_v1 path
("Screencasting with Wayland's protocol" in the log), NVENC encoder.
Environment
Reproduction
- Hyprland with one physical 4K monitor + one headless output (e.g.
hyprctl output create headless SUNSHINE), Sunshine output_name = the
headless output, capture = wlr
- Stream for ~1 hour; periodically measure unattributed VRAM =
nvidia-smi --query-gpu=memory.used minus the process sum
- Disconnect the client — leak does not drop
systemctl --user restart sunshine — leak drops to baseline instantly
Expected behavior
DMA-BUFs used for capture should be released when the frame is consumed; VRAM
usage should stay flat (minus normal encoder buffers) for the session
lifetime and drop on client disconnect.
Describe the Bug
Streaming from a virtual headless output leaks VRAM as orphaned DMA-BUFs that
are visible in neither
nvidia-smi's process list nor any process's fd table.The leak accumulates continuously (~1.3 GB/h) while a stream is active, and
survives client disconnect — only restarting Sunshine frees it.
Measured on an RTX 5090 32GB over two sessions:
systemctl --user restart sunshine(24893 → 2723 MiB)streaming, stays flat after client disconnect, grows again on reconnect
Key observation: leaked buffers match the physical monitor, not the streamed one
/sys/kernel/debug/dma_buf/bufinfo(as root) shows thousands of leakedbuffers with refcount 2 and no attached devices:
(
output_name = SUNSHINE), i.e. the leaked buffers are the wrong size forthe capture target — they appear to be allocated per capture cycle against
the physical display and never released.
Config
Hyprland (Wayland). Sunshine uses the
zwlr_screencopy_manager_v1path("Screencasting with Wayland's protocol" in the log), NVENC encoder.
Environment
(includes fix(linux/kmsgrab): fix handle leak in update_cursor #4757, fix(linux/wlr): Fix dmabuf buffer params protocol violation/leak #4588, wlr-screencopy capture targets wrong render node on multi-GPU NVIDIA systems, causing FD leak and VRAM exhaustion via failed dmabuf imports #5023 — behavior persists)
the leak is only visible via dma_buf/bufinfo and by diffing
nvidia-smi --query-gpu=memory.usedagainst the attributed process sum.Reproduction
hyprctl output create headless SUNSHINE), Sunshineoutput_name= theheadless output, capture = wlr
nvidia-smi --query-gpu=memory.usedminus the process sumsystemctl --user restart sunshine— leak drops to baseline instantlyExpected behavior
DMA-BUFs used for capture should be released when the frame is consumed; VRAM
usage should stay flat (minus normal encoder buffers) for the session
lifetime and drop on client disconnect.