Closed
Description
I just upgraded to iOS9 and Xcode 7, and found that GPUImageVideoCamera seems to be leaking ... at least the memory usage is growing at a fine steady rate over time :-O
I tested the SimpleVideoFilter sample, just disabling the xcode 7 bitcode option to make it compile.
Also, Movie input seems to be working fine, indicating that its related to the camera.
Anyone?
Activity
rued commentedon Sep 18, 2015
A quick narrowing down seems to point at didOutputSampleBuffer and the usage of runAsynchronouslyOnVideoProcessingQueue .... which really doesn't make sense to me.
Brad can you reproduce this?
Thomasgeley commentedon Sep 22, 2015
Same here,
Memory is increasing slowly (about 0.25mb/s), in my project and the sample projects.
Any hint on this ?

rued commentedon Sep 22, 2015
While waiting for Brad to comment on this, I found the following temporary "fix".
The problem seems to be in runAsynchronouslyOnVideoProcessingQueue, and I found that if we force a call to block(), and bypass all the "detect right queue" code, it doesn't leak anymore.
This is not my proudest moment, and it might introduce other issues somewhere else, or add performance penalties due to the forced synchronous behaviour.
rued commentedon Sep 22, 2015
The "fix" mentioned introduces some other issues with our real app :-/
So I'm back at finding a real solution.
One theory is that dispatch_async leaks. This is speculated here:
https://twitter.com/duobham
However I found that if I exchange the videoProcessingQueue with dispatch_get_main_queue or dispatch_get_global_queue it doesn't leak. This indicates that the error might be with the dispatch_queue_create.
rued commentedon Sep 23, 2015
It seems to be on device only and only when running in the debugger from Xcode.
So at least it's not a showstopper now for sending builds to testers or test outside the debugger.
It does however hide other real leaks :-/
BradLarson commentedon Sep 23, 2015
So I spent some time looking into this, and I think it's an artificial memory accumulation due to the way Xcode hooks into an application. If I run an application under profiling in Instruments, I see nothing accumulating between marked generations (heap shots) as video filtering proceeds. I also don't see accumulation in system activity, VM sizes, or anything else.
I do see the same sort of memory accumulation when running under the debugger in Xcode. Interestingly, if you transfer that debug run over to Instruments, you see the same buildup:
However, you'll notice that the source of the buildup appears to be "VM: Performance tool data", and if you drill down into that, the source is libBacktraceReporting.dylib. That certainly makes it sound like Xcode itself is the source of the memory buildup, not GPUImage.
I can't find any evidence that something is leaking or not being cleaned up properly on my end, so I'd hold off on screwing with the dispatch queue code. That most likely will impact your performance and potentially lead to crashes.
If you run this outside of Xcode, it looks like this memory accumulation goes away. While annoying for debugging, it shouldn't impact users any.
rued commentedon Sep 23, 2015
Thanks for looking into this!
Having researched on this myself, I agree that this has nothing to do with GPUImage - its solely related to dispatch_async in combination with dispatch_queue_create.
In addition, the leak seems to be present only when running the app on a physical device from the debugger, indicating that it must be an Apple rooted bug.
Still, I hope they address this soon, since the leakage camouflages real leaks.
erickingxu commentedon Nov 28, 2015
Hi @rued ,
I met the same problem about this memory grows up, but I try to force call the block() in runAsynchronouslyOnVideoProcessingQueue, it still had memory leak when I using SimpleVideoFilter example. And if the memory increase to 100M, the app terminated as a warning "Received memory warning.
Message from debugger: Terminated due to memory issue"
So I want to know how to fix it completely, do you look into it for dispatch_queue_create and some advice from you?
rued commentedon Nov 28, 2015
Hi Eric,
What I found was that this issue has nothing to do with GPUImage. It's solely showing itself when running your app on the device from Xcode. So the good news is that is doesn't appear when just running the app. It does however hide any real leaks, which is why I have been rather focused on it.
I just tested with Xcode 7.1.1 using this snippet. And it still leaks unfortunately.
Cheers
Thomas
+++
#import "ViewController.h"
@interface ViewController ()
{
dispatch_queue_t queue;
}
@EnD
@implementation ViewController
(void) run
{
dispatch_async(queue, ^
{
NSLog(@"Hello");
});
[self performSelector:@selector(run) withObject:nil afterDelay:0.01];
}
(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
queue = dispatch_queue_create("com.test.leak", NULL);
[self run];
}
(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@EnD
erickingxu commentedon Nov 29, 2015
Hi @rued ,
Thanks for your answer, I try your code and replace the dispatch_queue_create with dispatch_get_main_queue, it is seem to be no leak, but I try using it into GPUImage and do a switch action for different filters ,I found app(release) still leak at every switch action. It still not work. If you had time for look into it, and some details you can refer to #2137 .
rued commentedon Nov 29, 2015
Hi Erik,
To use the main queue doesn't sound like a valid solution to me, since it will stall the main queue and work against a general parallelism paradigm.
Cheers
Thomas
erickingxu commentedon Nov 30, 2015
Hi, @rued
I found if we use dispatch_create_queue("com.gpuimage.xxx",DISPATCH_QUEUE_CONCURRENT) to create a parallelism queue for gpu processing frames. The memory is stable and seems to be no leak.
@BradLarson ,do you think it is reasonable for gpuimage?
BradLarson commentedon Nov 30, 2015
@erickingxu No, using a concurrent queue in place of the standard video processing queue is completely unsafe. You need a serial dispatch queue to guarantee no simultaneous accesses to the OpenGL context.
About the memory buildup, read what I wrote above. This largely appears to be an artifact of how Xcode debugs the application. Run the application directly and this most likely won't be a problem.
erickingxu commentedon Dec 1, 2015
Hi, Brad and rued,
I got it.
Thanks from EK
soleo commentedon Dec 17, 2015
@erickingxu @BradLarson @rued , I think it's related with onevcat/DispatchMemoryLeakDemo#2, and another developer suggested a way to work around. I haven't tested it yet, but could be useful if you're trying to figure out there are other leaks in your app.
erickingxu commentedon Dec 29, 2015
@soleo ,thx. This method maybe avoid all queue memory leak. But it is surely good for check others leaks in app. Hope apple can fix it soon...
Merge pull request #2228 from RetVal/master
BradLarson commentedon Apr 3, 2016
I believe this is addressed in the latest pull request.