iPhone4 iOS5 ARC how to profile memory? - objective-c

I'm trying to debug a mysterious app crash that happens after running the app for a few hours.
My hunch is that this may be memory related, as I've not done any memory optimization since starting to build my app.
I'm looking at my application with the "allocations" instrument and I see these numbers:
All allocations 4.70mb
Living 51072
Transitory 357280
Overall Bytes 100.23mb
Overall 408000
Which is the important number here? Does my app take 4.7 Mb of memory or 100 Mb? At which point should I be concerned about my app being killed for memory reasons? I want to avoid premature optimization :)
Since I'm using ARC and TabBarController, most of the controller related memory seems to be out of my hands, unless I find out how to create a tab and lazily init a controller when that tab is first touched.
Thank you!

Related

How to programmatically purge/clean cocoa application memory?

I'm working on a Mac app. Initially monitoring Xcode's memory report while I ran my app showed showed the memory was just ramping up crazy. I used Instruments and profiled my app for allocations and leaks. Turned out there wasn't much leaked memory as you would expect due to strong reference cycles etc. However there was a lot of abandoned memory. By following the stack trace that lead to my code I have fixed by 70% using autorelease pools etc. Still the remaining 30% of abandoned memory seems to point system calls.
Now I have two questions based on that I have two questions
1) I want to fix the remaining 30%. How can I get rid of abandoned memory? I have already used Instruments and know exactly where those system calls are spawned but still dont know what to do to have that memory be cleaned up. (using ARC no manual retain/ release and autorelease doesn't seem to make a diff.)
2) After I know whatever my application was doing has completed and there is no need for any memory to be there (just like the application first started) I want to get rid of all memory that my app has used up. This I plan to use as a brute force approach to clean up all memory just like the system would if the user closes the app or turns off the system.
Basically if I know where my apps memory is in the file system I'll just programmatically call purge command on that or something similar. Because at this point I'm 100% sure nothing needs to be in memory for the app except for the first screen that you would expect the first time you launch the app.
I read this, this, this and this but they weren't helpful.

Is too much memory allocation in Instruments bad?

I am playing around with Instruments. And I just recorded/profiled for memory leaks, I had very few memory leaks, but an overwhelming amount of allocations just keep going even when my app just opened. Here is a screenshot after using the app for less than 10 seconds.
And as I keep using the app it just keeps increasing and increasing.
The weirdest part is most of the allocations are coming from classes I don't know like:
Foundation
Altitude
lbdispatch.dylib
But it could be from the SBJson and the other classes I imported and added for JSon and XML.
But is this a lot of memory allocations? Is too much bad???
Yes and no, it depends on what you are doing, if you allocate for example a lot of strings, lets say you allocate 1000 strings these allocation perse are not bad, but it depends on your logic view of your application, if you really need all the strings at once and you need them to be allocated and alive through all the steps of your application, then you dont have anything to do, your application just needs alot of memory,
However on the other hand, you may find some other ways to logically structure your application, like for example you could only allocate each of the 1000 string once you need it.
A very abstract answer is, if your app requires a lot of memory and there is no way to use some techniques such as lazy loading, or caching, then you dont have any other solution
But if you can restructure your application to use lazy loading, caching, allocation pools it would bee better
Please note: that you could let iOS sdk help you, by implementing correctly the memory warning callbacks in your application, in such a way that whenever you receive a warning, you start releasing any resource that you dont currently need
Also, do you have Zombies on? Zombies default to not actually removing any allocations, so memory is never deallocated. Always test for memory leaks with Zombies off.

App crashes on launch with < 256 RAM iOS Devices

The Info
I recently launched an app on the AppStore. After testing on the simulator thousands of times, and actual devices hundreds of times we finally released our app.
The Problem
Reviews started popping up about app crashes when the user launches the app. We figured that the app crashes on launch on iOS devices with less than (or equal to) 256 Mb of RAM. The following devices are devices our app supports with less than 256:
iPod Touch 4G
iPhone 3GS
iPad 1
The app doesn't always crash. Sometimes it launches fine and runs smoothly. Other times it crashes. The time from launch (when the user taps the icon) to crash is usually two seconds, which would mean that the system isn't shutting it down.
Findings
When using Instruments to test on certain devices, I find the following:
There are no memory leaks (I'm using ARC), but there are memory warnings
Items are being allocated like crazy. There are so many allocated items, and even though I'm using ARC it's as if ARC isn't doing what it's supposed to be doing
Because of what I see as "over-allocation", the result is:
This app takes (on average) 60 MB of Real Memory and 166 MB of Virtual. When the app launches the memory being used quickly increases until it reaches about 60 MB at which point the view has been loaded.
Here is a snapshot of the Activity Monitor in Instruments:
I know that those figures are WAYY to high (although the CPU % never really gets up there). I am worried that ARC is not working properly, or the more likely case: I'm not allocating objects correctly. What could possibly be happening?
The Code and Warnings
In Xcode, there are only a few warnings, none of which pertain to the app launch or any files associated with the launching of the app. I placed breakpoints in both the App Delegate and my viewDidLoad method to check and see if the crash occurred there - it didn't.
More Background Info
Also, Xcode never generates any errors or messages in the debugger. There are also no crash reports in iTunes Connect, it just says, "Too few reports have been submitted for a report to be shown." I've added crash reporting to my app, but I haven't released that version.
A Few Questions
I started using Obj-C just as ARC arrived, so I'm new to dealing with memory, allocation, etc. (that is probably obvious) but I'd like to know a few things:
How can I use #autoreleasepool to reduce my memory impact? What do I do with memory warnings, what do I write in the didRecieveMemoryWarning since I'm using ARC?
Would removing NSLog statements help speed things up?
And the most important question:
Why does my app take up so much memory and how can I reduce my whopping 60 MB footprint?
I'd really appreciate any help! Thanks in advance!
EDIT: After testing on the iPhone 4 (A4), we noticed that the app doesn't crash when run whereas on devices with less than 256 MB of RAM it does.
I finally solved the issue. I spent a few hours pondering why my application could possibly take up more RAM than Angry Birds or Doodle Jump. That just didn't make sense, because my app does no CALayer Drawing, or complex Open GL Graphics Rendering, or heavy web connection.
I found this slideshow while searching for answers and slide 17 listed the ways to reduce memory footprint. One thing that stuck out was PNGCrush (Graphics Compression).
My app contains a lot of custom graphics (PNG files), but I hadn't thought of them affecting my app in any way, apparently images (when not optimized properly) severely increase an applications memory footprint.
After installing PNGCrush and using it on a particularly large image (3.2 MB) and then deleting a few unused images I ended up reducing my apps memory footprint from 60+ MB and severe lag to 35 MB and no lag. That took a whopping five minutes.
I haven't finished "crushing" all my images, but when I do I'll update everyone on the final memory footprint.
For all those interested, here is a link to a blog that explains how to install PNGCrush (it's rather complicated).
UPDATE: Instead of using the PNGCrush process (which is very helpful, although time consuming with lots of images) I now use a program called ImageOptim that provides a GUI for multiple scripts like PNGCrush. Heres a short description:
ImageOptim seamlessly integrates various optimisation tools: PNGOUT, AdvPNG, PNGCrush, extended OptiPNG, JpegOptim, jpegrescan, jpegtran, and Gifsicle.
Here's a link to the website with a free download for OS X 10.6 - 10.8. Note, I am not a developer, publisher or advertiser of this software.

iOS app eating nearly 40mb at start

Hey, now when I finally got to test my app on a device it eats 40mb memory at the beginning which is a huge amount. Is there any good way to determine where exactly things went wrong?
Yes, use the memory allocations and leaks profilers that are part of the Instruments application.
You'll probably want to profile it using the Instruments app that comes with Xcode.

Why is my app getting didReceiveMemoryWarning and gets killed although memory is constant and there is enough memory available?

I'm having strange effects with my app. I implemented my own PDF viewer. It shows ONE page at a time. Using Instruments Activity Monitor I see that my real memory is constantly at around 50MB.
After switching pages forth and back a couple of times I receive a memory warning level 0.
I do my best to react on it and sacrifice the low-res background image I'm rendering first to show something until CATiledLayer catches up.
Does not help. A few pages later I get memory warning level 1 and level 2 and after a few more pages my app gets killed with reason "9". Memory NEVER goes above 50MB!
Why do I get those warnings in the first place? There IS enough memory available.
This is happening on on iPad running iOS 4.3.
I don't think there's anything mysterious going on here -- which I'm sure is not what you wanted to hear. There are no absolute figures of "safe" amounts of memory to use. The rule is: when the OS tells you you're using too much, use less. It will jettison background processes first and in preference to your foreground app but there are still limits.
In the "olden days," you used to be lucky to get 20Mb. I'm sure you can safely get more than that on an iPad but, apparently, it's less than 50Mb.
You don't say how much memory you free by releasing the background image, but it seems that you need to be caching less data. You might also want to check Leaks (also in Instruments) to make sure you're releasing the objects you think you are.