Releasing allocations in response to low memory warning, but app still crashes
I'm building an app for viewing photos I pull down from an API. Each photo is ~1MB in size. I've set up a "slideshow" to show a photo, then move onto the next one, like a user would actually use the app. I'm testing on an iPad 1 in Instruments.
When my app receives a low memory warning, I'm dumping all photos that are currently not being displayed to the user, as well as all cached model data returned from the API. I'm seeing a significant drop in my allocations in Instruments, and a similar drop in the virtual memory use. Even with this drop in consumed memory, my app is still being killed by the OS.
The application responds to 2-3 memory warnings without crashing before being terminated.
I've recently switched to ARC, so maybe there's something I'm not understanding? I assume setting my references to nil is sufficient. Here's my code for the in-memory models dumping their image data:
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSLog(@"Received memory warning; clear image for photo named \"%@\"", _name);
_image = nil;
_imageThumbnail = nil;
}];
Which is getting called. I also have an NSMutableDictionary which I'm calling removeAllObjects on when I received the low memory warning. I'm getting the following in the device console:
Oct 5 19:43:46 unknown configd[25] <Notice>: jetsam: kernel termination snapshot being created
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.accessoryd) Exited: Killed: 9
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.locationd) Exited: Killed: 9
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.mediaserverd) Exited: Killed: 9
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (UIKitApplication:com.500px[0xd492]) Exited: Killed: 9
Oct 5 19:43:47 unknown kernel[0] <Debug>: launchd[1996] Builtin profile: accessoryd (sandbox)
Oct 5 19:43:47 unknown ReportCrash[1999] <Error>: libMobileGestalt loadBasebandMobileEquipmentInfo: CommCenter error: 1:45
Oct 5 19:43:47 unknown ReportCrash[1999] <Error>: libMobileGestalt copyInternationalMobileEquipmentIdentity: Could not get mobile equipment info dictionary
Oct 5 19:43:47 unknown ReportCrash[1999] <Error>: Saved crashreport to /Library/Logs/CrashReporter/LowMemory-2011-10-05-194347.plist using uid: 0 gid: 0, synthetic_euid: 0 egid: 0
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : <NSThread: 0x1cd31410>{name = (null), num = 1}
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : {
OSMemoryNotificationLevel = 0;
timestamp = "2011-10-05 23:43:47 +0000";
}
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : <NSThread: 0x1cd31410>{name = (null), num = 1}
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : {
OSMemoryNotificationLevel = 0;
timestamp = "2011-10-05 23:43:47 +0000";
}
Oct 5 19:43:48 unknown com.apple.locationd[1997] <Notice>: locationd was started after an unclean shut开发者_JAVA技巧down
Oct 5 19:43:49 unknown SpringBoard[29] <Warning>: Application '500px' exited abnormally with signal 9: Killed: 9
Does anyone have any idea why my app is being killed even though it's freeing memory?
_image = nil;
_imageThumbnail = nil;
This is just setting the pointers to nil
, not releasing the actual objects. Release the objects, then they'll get deallocated (if their retain count hits 0).
Since you're using ARC, just set the properties to nil.
Turns out I was hanging onto references to the model classes somewhere else - they weren't getting dealloc'd, even if they released their image data during memory warnings. Eventually there were too many of them and the app crashed.
精彩评论