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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to