Silly ARC question - explanation requested
Silly ARC question - explanation requested
- Subject: Silly ARC question - explanation requested
- From: Alex Zavatone <email@hidden>
- Date: Wed, 04 Jun 2014 15:24:15 -0400
I was just reviewing a team member's code on iOS 7 for reading the CVPixelBuffer from a video frame, storing it in a UIImage and converting to grayscale.
Was testing against 720p video in the iPad and was pretty surprised to see memory leak faster than I've ever seen before, but only after our convert to grayscale utility function was called (which exists in an external lib).
Pretty surprised, I ran Instruments and saw that on every frame grab, the convert to grayscale allocates 3.52 MB of memory, but this wasn't being marked as a leak, which was surprising and it wasn't being released later on even if I nilled the local that it was assigned to.
As it turned out, my coworker had created a dispatch_async thread to start processing the video and within it, started at a framecount of 0, incremented it within a while(true) loop and grabbed the frame every time there was a new framePixelbuffer. All within the while(true) loop.
Well, OF COURSE memory's not going to be released and of course it's not a leak, but here's where I need some help understanding how to explain this and why this approach is a bad idea within Cocoa.
Within the loop, we do have another routine that draws items and to get it to not be a memory pig, he placed this within an autoRelease pool. That works. Memory is released as expected.
Great. (Though ugly).
But within the convert to grayscale routine in the external lib where we create a CGContextRef and later issue a CFRelease on it, memory is allocated within CGContextDrawImage. However it builds up for every frame grabbed and is not released until the while loop is exited. This is where we lose 3.52 MB each pass, but it's not really lost since it's allocated but can't be released by ARC since it's within a while loop.
So I put the "leaking" grayscale conversion code in the external lib in an autoRelease pool as well and memory was released too, just as expected.
OK. Sure. This works, buuut.
My first inclination is, "DUDE. You silly rabbit! You created an async process, then wrapped the whole video processing section in a while loop and you expected memory to get released by ARC? ARGH! WHY? Bad codemonkey, bad!"
His response was "Well, I was able to autorelease any offending bits within the loop without a problem, what's the big deal?"
Yeah, buuuut.
I'm trying to find a good way to explain to him that even though you can do things this way, Mr. Damn Competent Dot Net Programmer, but this is pretty much opposite to the way Apple wants you to code in Cocoa and it will make our lives sadder than wet puppies in the rain if we think this is OK.
He has a good point though - "don't you want to make our routines in our libraries robust or 'memory friendly'? We have access to our own source, but what about for all the libs we use where we don't have access to the source?"
Weeelll, yeah, sort of.
This is where I'm seeking a better explanation than I can give. Does anyone have a better explanation for "this is why we never do things this way - even though you can wrap time consuming operations in repeats and whiles, it doesn't mean that you should and expect ARC to work"?
About the "well, don't we want to use autorelease pools in our external libs to make them more memory friendly in case they are called from repeats or whiles?" point, what are your thoughts on that one as well?
Thanks in advance.
- Alex
"He who is immune to the the horrors of using SVN in Xcode"
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden