Go Back   DisplayLink Forum > DisplayLink Graphics Technology > Mac Software
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old Yesterday, 05:53 PM   #1
ksmith
Junior Member
 
Join Date: Jun 2022
Posts: 4
Exclamation DisplayLink Manager 16.2.39: long-running heap growth in `DisplayLinkUserAgent` and `

**Date:** 17 August 2026
**Issue:** After approximately 27 days, `DisplayLinkUserAgent` and `CrashRestartHelper` retained about 10 GiB of private heap memory and accounted for nearly all swap use on a 24 GB Mac.

## Environment

| Item | Value |
|---|---|
| Mac | MacBook Pro Mac16,7; Apple M4 Pro; 24 GB RAM |
| macOS | Tahoe 26.5.2, build 25F84 |
| DisplayLink Manager | 16.2.39 |
| Dock | StarTech.com Universal Dock; USB VID `0x17e9`, PID `0x6000`; parent DK30C2DPSS |
| Displays | M27Q 2560×1440 at 144 Hz; Dell S2716DG 2560×1440 at 60 Hz |
| Mode | Extended, mirroring off |
| Uptime | System: 34 days; DisplayLink processes: approximately 27 days |

Serial numbers and unique identifiers are omitted.

## Summary and impact

This is private `MALLOC_SMALL` heap growth, not primarily graphics buffers or an application-family accounting artifact.

| Process | Footprint | RSS | Default malloc zone | Live allocations |
|---|---:|---:|---:|---:|
| `DisplayLinkUserAgent` | 5.3 GiB | 178 MiB | 5.1 GiB | 30,458,950 |
| `CrashRestartHelper` | 4.8 GiB | 7 MiB | 4.8 GiB | 50,752,352 |
| `DisplayLinkXpcService` | Small | 6 MiB | No outlier | — |

System state at capture:

- 23.0 of 24.0 GiB physical memory used
- 9.8 GiB compressed memory
- 10.1 of 11.0 GiB swap occupied (92%)
- 120 MiB unused; `memory_pressure` reported 35% available

Almost 9.9 GiB of the two processes' private dirty heaps had been swapped out, explaining why their RSS was small. No new swap-outs occurred during the single snapshot, but the occupied swap reflected earlier pressure.

## Memory evidence

`DisplayLinkUserAgent`:

```text
Physical footprint: 5.3G (peak 5.3G)
Writable: 5.6G total; 5.1G written; 166.1M resident; 5.1G swapped

REGION SIZE RESIDENT SWAPPED
MALLOC_SMALL 5.0G 13.1M 5.0G
MALLOC_LARGE 69.2M 27.0M 42.2M
IOAccelerator (graphics) 119.7M 115.1M 1.1M
IOSurface 159.5M 4.6M 4.6M

DefaultMallocZone: 5.1G; 30,458,950 allocations; 5.1G allocated
```

`footprint` attributed 5129 MB to `MALLOC_SMALL`, compared with about 115 MB to graphics acceleration, 82 MB to unmapped graphics footprint, and 4.6 MB to `IOSurface`. Display buffers therefore do not explain the 5.3 GiB footprint.

`CrashRestartHelper`:

```text
Physical footprint: 4.8G (peak 4.8G)
Writable: 4.9G total; 4.8G written; 3.7M resident; 4.8G swapped

REGION SIZE RESIDENT SWAPPED
MALLOC_SMALL 4.8G 592K 4.8G
MALLOC metadata 19.8M 256K 19.2M

DefaultMallocZone: 4.8G; 50,752,352 allocations; 4.8G allocated
```

`footprint` attributed 4878 MB of the helper's 4901 MB footprint to `MALLOC_SMALL`.

### Continued growth

A second `vmmap` measurement approximately two minutes later showed increasing live counts:

| Process | First count | Second count | Increase |
|---|---:|---:|---:|
| `DisplayLinkUserAgent` | 30,458,950 | 30,471,026 | +12,076 |
| `CrashRestartHelper` | 50,752,352 | 50,756,035 | +3,683 |

These are live objects, not cumulative allocation events. The rounded zone sizes imply average retained blocks of roughly 180 bytes in the user agent and 100 bytes in the helper.

## `CrashRestartHelper` root-cause hypothesis

This is based on static inspection of the shipped arm64 binary and should be verified against source.

The binary retains symbols for `DLMRestarter.isDLUAAlreadyRunning()`, `recordStartupCrash()`, `shouldRestartAfterStartupCrash()`, and `restart()`. Disassembly shows a loop that:

1. Calls `NSWorkspace.shared.runningApplications`.
2. Bridges the returned `NSArray` to a Swift array.
3. Searches for `com.displaylink.DisplayLinkUserAgent`.
4. Calls `CFRunLoopRunInMode` for 10 seconds when the agent is present.
5. Repeats.

The binary does not import `_objc_autoreleasePoolPush` or `_objc_autoreleasePoolPop`, and no autorelease-pool boundary is visible around this loop. Repeated AppKit/Foundation enumeration can create autoreleased internal objects even when returned objects receive explicit releases.

The observed increase—approximately 3,683 live objects in roughly two minutes—is consistent with hundreds of retained objects per 10-second poll. Please check whether a per-iteration `autoreleasepool { ... }`, or replacing polling with `NSWorkspace` launch/termination notifications, stops this growth.

This hypothesis applies only to `CrashRestartHelper`; `DisplayLinkUserAgent` has its own 5.1 GiB private heap.

## `DisplayLinkUserAgent` investigation

The user-agent binary is mostly stripped, so a five-second stack sample identified active subsystems but not historical allocation sites. Threads were mainly waiting in the AppKit run loop, `VirtualDisplayListener`, IPC/event dispatch, device management, and display-provider paths.

Please use a symbolicated build with Instruments Allocations or malloc stack logging. Sort by persistent allocation count and look for millions of approximately 180-byte objects. Compare:

- idle operation;
- sleep/resume and clamshell transitions;
- docking/undocking;
- resolution or refresh changes;
- the 144 Hz display at 144 Hz versus 60 Hz;
- video playback and screen sharing.

## Reproduction

The minimum time is unknown because the leak was found during normal long-running use.

1. Run DisplayLink Manager 16.2.39 with the dock and extended-display configuration above.
2. Exercise normal work, sleep/resume, docking, and display changes over multiple days.
3. Periodically compare live allocations:

```bash
for name in DisplayLinkUserAgent CrashRestartHelper; do
pid=$(pgrep -x "$name") || continue
echo "$name pid=$pid"
vmmap -summary "$pid" 2>/dev/null |
egrep 'Physical footprint:|MALLOC_SMALL|DefaultMallocZone'
done
```

Expected: live allocation count and footprint plateau after reaching steady state.
Actual: both processes retained tens of millions of small objects, continued growing, and occupied about 9.9 GiB of swap.

Quitting and reopening DisplayLink Manager reclaims the memory but is only a temporary workaround. Terminating only the helper may impair automatic recovery and is not a permanent fix.

## Upstream status

16.2.39 is the newest published release, and its notes do not mention this leak:

- <https://drivers.synaptics.com/products/displaylink-graphics/downloads/macos>
- <https://drivers.synaptics.com/sites/default/files/release_notes/2026-07/DisplayLink%20Manager%20Graphics%20Connectivity16. 2-Release%20Notes.txt>

macOS 26.6 is available, but Apple's public notes do not identify a DisplayLink memory fix. The helper hypothesis concerns code bundled with DisplayLink Manager.
ksmith is offline   Reply With Quote
Reply

Tags
memory leak, memory-leak


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 07:55 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2026, vBulletin Solutions, Inc.