Unity-Technologies / Unity-Technologies/com.unity.webrtc

[BUG]: Memory leak when receiving long-running video stream (iOS, Mac, Linux)

Open
#1,013 4 comments 1 reaction 1 assignee View on GitHub

@karasusan is already working on this.

Since Dec 18, 2023.

bug issued
Dominant language
Assembly
Stars
852
Forks
238
PR merge metrics
No merged PRs in 30d

Description

Package version

3.0.0-pre.6

Environment
* OS: ipadOS 16.6.1, Mac Ventura 13.4.1, Ubuntu 20.04 (IL2CPP and Mono)
* Unity version: 2022.3.5f1

Unity application connects to a live webrtc stream for long periods of time (>24 hours)
Steps To Reproduce
  1. Connect to a WHEP endpoint streaming a video track
  2. Observe memory increase every hour
Current Behavior

Memory will increase slowly over time (a few MB per 10 minutes)
On iPad, once memory limit is reached, the app will close without notification or crash log.

Expected Behavior

No memory leak.

Anything else?

Screenshot from Unity Memory Profiler snapshot comparison
Screenshot 2023-12-15 at 16 09 02

Screenshot from XCode leak profiler (snapshot taken every 10 seconds)
Screenshot 2023-12-15 at 16 05 02

Screenshot of XCode leak info. The 256 byte malloc is occurring at a consistent rate, leading to increased memory usage.
Screenshot 2023-12-15 at 16 06 27

Screenshot of leak callstack
Screenshot 2023-12-15 at 16 16 19

Judging by the callstack, the leaked memory appears to originate from the call to Marshal.StructureToPtr() in Contex.cs::Batch::Submit

(From here on is my conjecture, and I am not an expert in this area, so I may have misunderstood)

Reading the "Remarks" section in the Marshal.StructureToPtr documentation we see:

...All other reference types (for example, strings and arrays) are marshaled to copies. To release these managed or unmanaged objects, you must call the Marshal.DestroyStructure method before you free the memory block.

The BatchData struct contains an IntPtr array, so it might be the case that this array is being copied and never properly freed.
I tested by setting the fDeleteOld parameter to true, and the memory leak was resolved (tested on Mac only)
I think this is safe because the first StructureToPtr call happens when the Batch class is initialized (with fDeleteOld false, as it should be), and every call after that comes from Batch::Submit(). So the ptr variable will always hold valid data to free.

Please let me know if I can be of assistance in any way.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.