Memory leaking as NSManagedObjectIDs after performing mapping operation

96 views
Skip to first unread message

RobB

unread,
Jan 13, 2014, 3:45:14 AM1/13/14
to res...@googlegroups.com
Hi all,

I'm seeing large amounts of memory leaking while RestKit is mapping objects on a background thread. Initially I thought this was only happening with iOS 7, since it seems to be affecting our customers running that version more than those still on iOS 6, but I've gone back and profiled by building the app in Xcode 5 using the iOS 7 SDK, and Xcode 4 using the iOS 6 SDK and the results are the same. The net result for the user is that after performing a lot of network access, the device runs low on memory and the app eventually gets killed by iOS.

The leaked objects I see are all NSManagedObjectIDs that are created by the RKEntityByAttributeCache when mapping objects received from the server, as part of the mapping operation performed on the background thread. These are only small (16 bytes) but some of our data sources are very large (tens of thousands of objects), and we have many data sources. So for a source with say 10,000 objects, we leak 156 KB. Repeat this for a number of sources that may have many more objects, and we are quickly leaking many MB of memory.

I can't actually find any memory leak in RestKit, in particular in the RKEntityByAttributeCache. After the mapping operation completes, it gets dealloced and releases its dictionary cache (usually the cache gets flushed before then, so it releases its cache of NSManagedObjectIDs). Nothing else higher up the chain in RestKit looked suspicious either. So I can't tell where the problem lies... in our code that uses RestKit, in RestKit itself, or even in the CoreData library?

Is anyone else seeing memory leaks like these? For apps that sync less data it might not be noticeable unless you go looking for it, because the leaked amount would be trivial.

To complicate things further, the leaks instrument seems to hide some data or is unable to capture it correctly. When examining the leaked NSManagedObjectIDs, and looking at the reference count details for a particular object, the retain count can jump by several values without showing an entry. e.g. it can go from 2 to 4 without an entry saying how it got from 2 to 3. And when being released after the mapping operation, it can be 5 in one entry and then 2 in the next entry, giving no indication of how it went 5 to 4, 4 to 3 and 3 to 2. Is this some bug or limitation of the Leaks instrument? It makes working out the pairing of retains/releases impossible. e.g. the only time the app is shown as the responsible library (as opposed to CoreData or Foundation) is the RKEntityByAttributeCache:addObject call, and there is no equivalent for the RKEntityByAttributeCache:flush or RKEntityByAttributeCache:dealloc, even though when I debug I can verify that these are being called and the NSManagedObjectIDs are being released.

Here's a screenshot from Leaks to show what I mean about the missing entries, and it also shows the RestKit callstack for the entry that's actually attributed to the app code (as opposed to Apple libraries).



Also note we are using RestKit 0.10.1, and can't yet upgrade to the latest RestKit version, because 0.20.x swapped out the networking library for AFNetworking and unfortunately we build a custom sync engine around RestKit specific to our needs, and it's all built on top of the RestKit networking code. So it's going to require a large re-write to make it all work with the latest RestKit version, which we plan to do in the future but can't do right now.

Does anyone know what I'm missing here, and how to find where the memory leak is? Can anyone see NSManagedObjectIDs being leaked in your apps?

Thanks in advance!

Agworld - Connecting the Industry

ABN: 82 136 483 951
Visit us at www.agworld.com.au or follow us on 
Facebook Twitter Google Plus Linkedin
Reply all
Reply to author
Forward
0 new messages