Reputation: 3384
Is it is possible to write an app that uses 200MB, say? My iPad has 1GB, but I get
didReceiveMemoryWarning
after using 20 or 30MB and shortly after my app is killed. (I am the foreground app so I don't really see why I have to get this warning, why doesn't the OS close the background apps, but whatever). I am taking no action in didReceiveMemoryWarning (just logging it and calling super), is that why I am killed? Or is there other possible reasons?
So I understand I am supposed to free-up memory when I get the warning, but I don't want to! (Lets assume my app REALLY does need 200MB to operate).
If I did free-up some memory when I get the warning (how much?) then would my app then not be killed? And could I then carry on and use up MORE memory? If so I could create some "balloon" memory just so i can free it when warned and then at least my app survives. This seems insane though.
Or is it basically impossible to have an iPAD app that uses more than a few 10s of MB?
Upvotes: 4
Views: 3567
Reputation: 101
Something is not right. Any app can use about 1/3-1/2 the total physical ram on any device under most any version of iOS from 6-8 without being jetslammed (killed)
I can write a simple app that instantly takes 400mb on a 1gb device, and it's not killed - unless iOS can't terminate other services fast enough.
IOS 8 is more forgiving vs 6 or 7 as many of the launchdaemons now have a jetslammed priority flag which decides which order things get killed - as well as a memory limit so if a LD exceeds that high water mark, it's killed. IOS should let any app keep using memory until all the lower priority jetslammed services have been killed off. There's also another setting for LDs that terminate them when memory is under pressure - regardless of JS priority.
Once all that's left are services with a higher priority than a user app, that's when jetslamms/kills or should get memory warnings before it gets slammed
Programming on the iPad 6 (air 2) is MUCH easier. 2gb ram. 300-400MB free after boot and iOS will back down to using 700MB allowing 1.3GB for an app.... And I bet the iPhone 7 and mini 4s will have 2gb. That will let us see play station 3, or better games, for iOS IF AND ONLY IF users will pay the price of a normal PS3 game (20-80$). Most ppl will complain, but most spend more on these free to pay (play) apps with 4.99$-129.99$ iAps - absurd (Apple should limit iAps to 29.99)
Gone are the days of the 10% rule (where your app should use no more than 10% system ram)
Look at more hardcore, major iOS games.... They use 300-400MB on 1gb devices and won't run on 512mb devices.
So if you are being killed for 30MB something really is not right.
Upvotes: 0
Reputation: 62323
I recently had this problem. It basically comes down to the speed at which you allocate memory. If you try to grab a lot of memory up front then iOS will terminate you for using too much memory and not responding to memory warnings. iOS memory handling is ridiculous really. The worst thing is that my problems only arose AFTER I'd released the app on the app store. It took me ages to track down what the problem was :(
The way I managed to handle this was to allocate the RAM i needed at startup (64MB) slowly and hold off when I receive memory warnings. I create my own ViewController that displays an animated splash screen while I'm an initialising the memory usage In viewDidLoad I do the following (Meg is a simple inline function that multiplies by 1024* 1024):
AllocBlockSize = Meg( 2 );
mAllocBlock = (char*)malloc( mAllocBlockSize );
//[mpProgressLabel setText: @"Initialising Memory: 1MB"];
mpInitTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5f target: self selector: @selector( AllocMemory ) userInfo: nil repeats: YES];
In my AllocMemory selector I do this:
- (void) AllocMemory
{
if ( self.view == nil )
return;
if ( mMemoryWarningCounter == 0 )
{
if ( mAllocBlockSize < Meg( 64 ) )
{
mAllocBlockSize *= 2;
mAllocBlock = (char*)realloc( mAllocBlock, mAllocBlockSize );
ZeroMemory( mAllocBlock, mAllocBlockSize );
if ( mAllocBlockSize == Meg( 64 ) )
{
mMemoryWarningCounter = 8;
}
}
else
{
free( mAllocBlock );
// Initialise main app here.
}
}
else
{
mMemoryWarningCounter--;
}
}
And to handle the memory warnings I do as follows:
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
mMemoryWarningCounter += 4;
}
Also do note the ZeroMemory step. When I didn't have this here i would allocate 64MB and still get booted. I assume the touching the memory fully commits it to my app thus zeroing the memory was necessary to eliminate the memory warning and eviction problems I was suffering.
Upvotes: 2