How to debug iOS crash due to memory pressure

29,381

I solved the problem. In my case, the memory pressure, it was due to the constant memory usage by a run loop cycle. The loop is executed every second and works on data that must be analyzed and presented in the views. Another thing, the project initially was not using ARC. After a conversion project to ARC has occurred the problem.

Before the conversion of the project to ARC, at the end of the loop I had a direct call for the release of resources. With ARC of course this is done automatically, and the problem is just that. So for the class that runs the loop, I returned to non-ARC version and I used the tricks to make manually to release the resources that I used.

Autorelease pool blocks provide a mechanism whereby you can relinquish ownership of an object, but avoid the possibility of it being deallocated immediately (such as when you return an object from a method). Typically, you don’t need to create your own autorelease pool blocks, but there are some situations in which either you must or it is beneficial to do so.

@autoreleasepool {
    // Code that creates autoreleased objects.
}

At the end of the autorelease pool block, objects that received an autorelease message within the block are sent a release message—an object receives a release message for each time it was sent an autorelease message within the block.

You can place an @autoreleasepool block around any section of code, however you really shouldn't do what I think you're doing.

Autorelease is much less efficient than allowing ARC to add in retain and release calls for you, and it's potentially unsafe. Autorelease puts all of your objects in a "pool" and then when you're out of scope and/or whenever it decides to dump the pool, it "drains" the pool and the objects' retain counts get decremented by one.

The short answer: Leave out the @autorelease blocks completely unless Apple says otherwise in the documentation or the template (for example, main.m will have an @autoreleasepool in it).

This means that your objects could potentially get released before you really wanted them to. @autoreleasepool blocks are more useful for when you have a very tight loop of code that's going to instantiate and then discard a massive amount of objects. For example, a for loop that processes a huge database and allocates string objects and then uses those string objects to fill the properties of instances of a class you've created. In this case, ARC may not release those objects reliably while you're inside the for loop and you may need to create an autorelease pool.

However, ARC not doing the right thing in a tight loop isn't very common. It's really more of a non-ARC concept, where you use an NSAutoreleasePool and you manually drain it.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

I hope I have helped others with the same problem.

Share:
29,381
andreapavan
Author by

andreapavan

MSC student in Computer Science at University of Udine. iOS Developer

Updated on July 16, 2020

Comments

  • andreapavan
    andreapavan almost 4 years

    I'm using ARC and the app crashes saying received memory warning. I'm testing the application directly on the device (iPhone 4 with iOS 7.0.2) and compiling with XCode 5 using iOS 6 SDK. I have used the apple instruments and I am having have around a 20MB LiveBytes allocated.

    App at start

    After 4-5 min my app has 30mb of memory.

    App status after 5 min

    After compiling and testing the app on device I see that crash after a few minutes, just after the memory warning message. Why do not happen crash using instruments? However I am trying to clear this problem for a month and can't get thing rite, and I really need help. It looks like I do not have any leaks but I cannot find where is wrong. Thanks in advance for any advice.

    • j9suvak
      j9suvak over 10 years
      I have an app that worked fine on my iPad 2... until I upgraded to iOS 7, now it crashed due to 'memory pressure'. Did you figure out how to resolve this?
    • MattLoszak
      MattLoszak over 10 years
      I have essentially the same problem, might post another question soon if I can't find the answer elsewhere.
    • andreapavan
      andreapavan over 10 years
      I solved my problem, check my answer.
  • Shizam
    Shizam about 10 years
    I think you came to an incorrect conclusion here, @autoreleasepools are still useful in ARC and not just in tight loops. I've seen @autorelease help with memory pressure issues in my app when dealing with large memory I/O outside loops. Also: stackoverflow.com/questions/9086913/…
  • Hitarth
    Hitarth over 9 years
    @andreapavan. i have same issue. i got 5k record from web service than i am inserting this all record to db. Everytime 3k record successfully inserted than app crash. My loop will run 5k time as i insert 5k record. so is it fine to implement autoreleasepool method in loop ?
  • andreapavan
    andreapavan over 9 years
    Mine was a rather special case because I had to get my hands on a project developed in several steps. As said Shizam,autoreleasepools are also useful if you use ARC. Typically, you do not need to create your own autorelease pool blocks, but there are some situations in which you either must or it is beneficial to do so. I had a problem between ARC and the block autoreleasepool. In the old implementation this was handled manually, and I kept that way. I indicated in the settings that the class does not use ARC and I managed the memory manually by using a block autoreleasepool where necessary.
  • andreapavan
    andreapavan over 9 years
    Also check this great response @mattjgalloway that provides further details regarding the blocks autoreleaspool using ARC. stackoverflow.com/a/9087002/1056493
  • Kevin Duong
    Kevin Duong about 9 years
    I'm having the same situation as @Coder. Did you find a solution for that @Coder?