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: David Duncan <email@hidden>
- Date: Thu, 01 Jan 2015 15:52:23 -0800
> On Jan 1, 2015, at 3:38 PM, Graham Cox <email@hidden> wrote:
>
> Hi all,
>
> I know I'm very, very late to the party, but I'm building my first ever project with ARC instead of manual retain/release (which I was always very comfortable with). Frankly, I'm finding it frustrating because it seems much harder to know how memory is managed. Anyway. I will plough on - no doubt I'll get used to it.
The first thing to keep in mind is that unless otherwise qualified, all object references are owned - locals, ivars, array entries, etc. The places where this isn’t possible (such as structs) are flagged as compiler errors. The lifetime of ownership can typically be considered as “usage scoped” - that is, the object is owned up until its last reference, where by default you can think of it as released. There are exceptions to both of these rules, but they are generally minor and many likely line up with your expectations as well.
The most prominent exception has to do with inner pointers to things that are not Obj-C objects (such as -[UIColor CGColor]) where ARC doesn’t take ownership of the returned object (because it isn’t an Obj-C object) and your last reference to the outer object (a UIColor in this case) ends before your usage of the inner non-object.
But thats just to help you understand/get used to ARC, it doesn’t likely apply to your issue at hand :).
>
> I'm using NSURLSession and NSURLSessionDataTask to fetch chunks of data from a .m3u8 playlist. It works pretty well, but I'm seeing a gradual increase in memory usage as my app runs. Under classical memory management, I would probably have little difficulty in isolating the problem, but with ARC I'm finding it much harder to track down because it's unclear when certain objects come to the end of their lives. Anyway, running in Instruments shows a constant list of calls to malloc() from HTTPNetStreamInfo::_readStreamClientCallBack(__CFReadStream*, unsigned long) in the CFNetwork library, allocating 132KB. These blocks are allocated at a high rate (over 100x per second) as the app runs, and as far as I can see are never freed. I'm not directly using this API, it must be something internal to NSURLSession.
>
> How can I ensure that these blocks are freed? I'm assuming that a leak in the OS of this sort would have been spotted, so my assumption here is that I'm doing something wrong that prevents proper freeing.
Generally the answer would be to stop referencing objects when you don’t need them anymore, but Instruments’s Allocations tool would be the most useful thing to use to debug this - in particular retain/release tracking would likely be the most useful way to debug this issue. I would suspect the memory blocks at hand are being allocated for receiving the downloaded data and possibly wrapped as NSData objects.
>
> The way I'm using NSURLSession seems to be "normal", as far as I can tell. I have an object that allocates a NSURLSession and this session exists for as long as the task runs, which can be a very long time. Each "chunk" of data is added to the session as a NSURLSessionDataTask and I supply a completion block. The completion block simply appends the data it receives to a file and fires off some notifications. The completion block may or may not schedule the download of the following chunk, depending on various factors, but it doesn't do anything special to tell the task it has finished - as far as I can tell from documentation, the fact the completion block is called is because the task has finished, so I can just forget about it.
>
> The session itself is invalidated when the owning object is dealloced, but that might be hours or days later when the user decides to discard the task. Otherwise it stays alive indefinitely. I'm wondering if that's the right thing to do? The docs suggest that a NSURLSession is somewhat like a tab in a web browser, so it lives as long as that tab exists.
>
> Any clues as to how I can track down the leak or whether there's an obvious missing step that should free temporary buffers used by NSURLSessionDataTask would be gratefully received at this point.
>
>
> --Graham
>
>
>
> _______________________________________________
>
> 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
--
David Duncan
_______________________________________________
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