Memory leak in MTLCommandBuffer?

I created two threads in my macOS app, a main thread that dispatches work every 40ms to a worker thread. This worker thread causes a memory leak. After some debugging it seems that the MTLCommandBuffer is the reason for the leak:


if let commandBuffer = commandQueue.makeCommandBuffer() {

  // some code here

  commandBuffer.commit()
}


I uncommented every code from the worker thread and there is no memory leak anymore. But when I add these lines above and create only an empty command buffer and commit it to the queue then the CPU memory will increase over time.

The app is running on macOS and compiled with Xcode 10.3 (and Xcode 11 beta with the the same effect).


Instruments cannot find any leaks. Persistent allocation stays constant over a long time. Only Xcode debugger shows this static memory increase. And only if I create a commandBuffer (with commands encoded or also when empty).


Edit: I created a new project in Xcode with the game template and selected metal. Same effect. The debugger memory section has the same memory increase over time (nearly 0.1MB each second).

Replies

This I believe is due to overhead involved with the debug tracking of Metal commands. I would love an official Apple response on this, but I think it’s safe to assume this 0.1mb increase will not exist in a release build of your application.


Anyone from Apple have ideas about what causes this tiny memory leak even in the template apps?

I had similar memory leak. In my case I forgot to put @autoreleasepool inside of function for displayLinkCallback.

Basically, display link is creating separate thread in plain C, without autoreleasepool.

Maybe you have something similar.

I am seeing the same issue in 2 codebases I am working on, one of which is multi-threaded and the other single threaded.


It is also reproducable in the official Apple Sample: https://developer.apple.com/documentation/metal/using_a_render_pipeline_to_render_primitives?language=objc


Just run the sample and watch the memory slowly increase over time. When working on memory limited platforms where you become "Terminated due to memory issue" when not even getting near to the devices RAM capacity, a leak which we have seeming no control over is extremely frustrating.

It seems that the commit() causes the memory increase. The MTLCommandQueue makeCommandBuffer call is not the problem. Only when you commit your command buffer you will the memory usage going up. autoreleasepool{} does not make a difference. Maybe it is not a bug but data stored in memory for debugging with Xcode.