"We offer new support options and therefor the forums are now in read-only mode! Please check out our Support Center for more information." - Vuforia Engine Team

Serious memory leak in native iOS demo

Hello Vuforia people --

We're working based on the native iOS demo with SDK 9.8.5 and the corresponding sample project, and have run up against a very bad memory leak related to Vuforia rendering with Metal.

After a bit of investigating, we found that the issue is also present in the sample app.  On an iPhone X test device running iOS 14.6, the app's memory use increases by over 3 MB per second.  The sample app crashes within a few minutes of opening the Vuforia window in image tracking mode.

A bit of work with the Xcode memory graph debugger led me to this bit in VuforiaView.swift:

 

if (prepareToRender(&viewportsValue, 
                    UnsafeMutableRawPointer(Unmanaged.passRetained(mMetalDevice!).toOpaque()),
                    UnsafeMutableRawPointer(Unmanaged.passRetained(drawable!.texture).toOpaque()),
                    UnsafeMutableRawPointer(Unmanaged.passRetained(encoder!).toOpaque()))) {
...
}

 

// Pass Metal context data to Vuforia Engine (we may have changed the encoder since
// calling Vuforia::Renderer::begin)
finishRender(UnsafeMutableRawPointer(Unmanaged.passRetained(drawable!.texture).toOpaque()), 
             UnsafeMutableRawPointer(Unmanaged.passRetained(encoder!).toOpaque()))

The passUnretained pointers seem to be the cause. Switching them to passUnretained seems to resolve the leak issue, but I'm concerned that will lead to memory corruption, and obviously the code was written with the passUnretained for a reason. My hope is that someone from Vuforia can shed some light on this, and tighten up the sample project in general. Thanks!

Hello,

Thank you for the investigation and report. I know we have been tracking some memory leaks, but unclear if it is related to your report.

I will escalate to the team for additional investigation.

Thanks,

Vuforia Engine Support

Hello @LocalProjects,

The team has confirmed that you are correct: calls to passRetained should be replaced with passUnretained. Additionally, as part of our Engine 10.0 release, we fixed another significant memory leak when changing between experiences.