4

I am loading large amounts of data into Core Data on a background thread with a background NSManagedObjectContext. I frequently reset this background context after it's saved in order to clear the object graph from memory. The context is also disposed of once the operation is complete.

The problem is that no matter what I do, Core Data refuses to release large chunks of data that are stored as external references. I've verified this in the Allocations instrument. Once the app restarts the memory footprint stays extremely low as these external references are only unfaulted when accessed by the user. I need to be able to remove these BLOBS from memory after the initial download and import since they take up too much space collectively. On average they are just html so most are less than 1MB.

I have tried refreshObject:mergeChanges: with the flag set to NO on pretty much everything. I've even tried reseting my main NSManagedObjectContext too. I have plenty of autorelease pools, there are no memory leaks, and zombies isn't enabled. How can I reduce my Core Data memory footprint when external references are initially created?

I've reviewed all of Apple's documentation and can't find anything about the life cycle of external BLOBS. I've also searched the many similar questions on this site with no solution: Core Data Import - Not releasing memory

Everything works fine after the app first reboots, but I need this first run to be stable too. Anyone else been able to successfully fault NSData BLOBS with Core Data?

Community
  • 1
  • 1
Jack Freeman
  • 1,414
  • 11
  • 18
  • Perhaps a code sample showing how you store and work with these BLOBs can be helpful. – Michał Ciuba Jan 23 '15 at 20:20
  • This is specific to Core Data. Create a NSManagedObject with an external NSData property. Queue up a NSMangedObjectContext and create lots of objects with dummy data on this property. You will not be able to clear this memory until the app is restarted, even if these objects are faulted or the context is reset. – Jack Freeman Jan 24 '15 at 20:18
  • I remember that I had a similar problem in my app. I replaced the property storing a BLOB with a relationship to a separate entity, having the BLOB as its only attribute. I would then call `refreshObjects:` on this entity's instances when they were no longer needed. This approach is recommended in this guide: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdPerformance.html#//apple_ref/doc/uid/TP40003468-SW5 – Michał Ciuba Jan 24 '15 at 20:25
  • I have done this exact approach. My problem is, that on ios8, faulting these objects do not clear them from memory. – Jack Freeman Jan 24 '15 at 20:32

1 Answers1

0

I'm assuming the "clear from memory" means "cause the objects to be deallocated" and not "return the address space to the system". The former is under your control. The latter is not.

If you can see the allocations in the Allocations instrument, have you turned on tracking of reference count events and balanced the retains and releases? There should be an indicative extra retain (or more).

If you can provide a simple example project, it would be easier to figure out what is going on.

bbum
  • 162,346
  • 23
  • 271
  • 359