Re: Debugging memory leak in NSURLSession with ARC
Re: Debugging memory leak in NSURLSession with ARC
- Subject: Re: Debugging memory leak in NSURLSession with ARC
- From: Roland King <email@hidden>
- Date: Fri, 02 Jan 2015 10:22:04 +0800
+1 for all of this. I wouldn't call leaks an utter waste of time, but it really does only find pure retain cycles (which it then annotates very nicely) and not memory which is really is pinned by a real reference which is more often the case. Also, if you're using KVO anywhere, this tends to entirely defeat leaks even though KVO isn't a strong reference and shouldn't be treated like one, it is. That makes leaks less useful than it could be for me because I'm always KVO'ing something.
There's an old blog by bbum which covered using generational analysis for finding leaks which aren't leaks. Xcode has changed quite a lot since then but some of the screens look quite similar even now. I routinely put my code through this torture test, it's so easy to run and the results are often very illuminating.
http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ <http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/>
I do remember there was a recent discussion on the dev forums about NSURLConnection 'leaking' in iOS8. It appears it wasn't actually leaking, but it did amass memory which it gave up in a delayed manner only when you stopped making requests. Again that's iOS, but I do wonder if the same code is in OSX and whether the same effect is there too. That discussion, which doesn't quite reach a conclusion, is here .. https://devforums.apple.com/message/1056669#1056669 <https://devforums.apple.com/message/1056669#1056669>
> On 2 Jan 2015, at 09:48, Quincey Morris <email@hidden> wrote:
>
> On Jan 1, 2015, at 17:20 , Graham Cox <email@hidden> wrote:
>>
>> I'm using Allocations, but I'm finding the volume of data a bit overwhelming.
>>
>> As an aside, Leaks shows nothing at all. Does that mean I'm not actually leaking anything?
>
> Forget Leaks, it’s an utter waste of time*****. Use marked generations. The persistent increase in each generation is your real “leak”.
>
> — In code where things happen repeatedly in the background, it can be hard to get your app into a quiescent state (in terms of allocations) so that you can find a good place to mark a new generation in Instruments. You may have temporarily add code to create and/or prolong such a quiescent state.
>
> — It’s generally not useful to *start* by looking at the retain/release history. You’ll find problem objects easily, but you won’t know where they came from or why they didn’t get released.
>
> — In the list of objects incrementally leaked in a generation**, look for the ones that you actually created (either objects of your own classes, or objects that were obviously created at a particular known place in your code). Out of those objects, try to eliminate the ones that appear to be “children” of others.
>
> — Ideally, you’ll find two sorta-kinda top-level objects remain. The presumption is then that there’s a reference cycle between them. For example, you might find that one is a window controller and the other is something in your data model***. Or, you might find that one is a block, and the other is whatever created the block****.
>
> — Audit the relevant source code. It’s often easiest and quickest to find the cycle just by inspecting the declarations/blocks.
>
> — Only if that goes nowhere is it time to start analyzing the retain/release history of a generation in Instruments. By now, though, you should have a vague idea of what you’re looking for.
>
> — Start by getting Instruments to pair as many retains and releases as it can automatically.
>
> — If that’s unproductive, start over and compare them all yourself. (But I should add that I haven’t spent much time doing this in Yosemite yet. The UI may be a bit different since Mavericks, and the auto-pairing may work a bit differently, too.)
>
>
> ** Create multiple generations, and look not only at what was leaked in each generation, but what’s repetitive in the pattern of leaks. Your real culprit should produce an identical pattern every time. Leaks unique to a generation aren’t what you’re looking for here. (I think this is the debugging equivalent of the second derivative.)
>
> *** That usually means a window delegate reference needs to be manually nil’ed when the window closes, because we learned how to do bad memory management in the bad old days.
>
> **** That usually means the block and the ‘self’ it captured mutually refer to each other. I’m betting this is what’s wrong in your case.
>
> ***** I should say, I’m not scorning Leaks. It’s just that experienced Obj-C developers tend not to make the kinds of mistakes that Leaks can detect. Experienced developers make other, better mistakes.
>
> _______________________________________________
>
> 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
_______________________________________________
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