Xcode Instruments: peak RAM of iPhone apps running in Simulator? - iphone

Is Activity Monitor (a.k.a. Memory Monitor) the only tool in Xcode Instruments that can measure the total app RAM usage of an iPhone app running in Simulator? Just that line showing momentary wired RAM?
And how accurate is that versus iPhone hardware, especially given OSX paging i/o to VM?
I'm seeing 7-8MB wired RAM figures for just the default Xcode iPhone project templates (other than OpenGL) compiled and running. At the same time Object Allocations shows well under 1MB for all objects.

Nope, there's a much better way to do it.
Go to the Run menu and select Run with Performance Tool then Object Allocations.
This will start Instruments and will show RAM usage. It's also useful for detecting memory leaks if you choose Leaks instead of Object Allocations.

I would agree, since the Simulator is just an "API simulator", the behavior you see is going to be at least somewhat dependent how OS X manages memory. And the restrictions are obviously different, for example you can exceed 128 MB of ram, or even 256 MB, which obviously isn't possible on any current iPhone or iPod Touch (at least, as of this writing...).
I've still found it useful in OpenGL for making sure textures and other items are properly deallocated, but beyond that, it's just a rough guideline.
However, if you want to see memory usage on device, there's a simple enough solution. Just target Device in Xcode, and go to Run > Run with Performance Tool > Object Allocations, then the build will be sent to the device and the Object Allocations tool will pop up next to Xcode and show on device memory usage.

Related

Profiling memory leaks with Instruments- huge difference between iPhone 4 and iOS 5 Simulator

When profiling my app with Instruments (looking for memory leaks), I get extremely different results with the iOS 5 iPhone Simulator from those I get with my iPhone 4 running iOS 5. The first picture shows the results from the profiling with the real device, and the second is with the simulator:
Real device:
iOS 5 Simulator:
This profile is taken up to the same point in the app in both cases: completion of viewDidLoad in the rootViewController's view lifecycle. I have waited in both of them for the total allocated memory to stable out. As you can see in the device graph, there are some extreme fluctuations occurring at about 00:10, which aren't present in the Simulator. On the real device, total allocated memory, at around 00:08, jumps from 1MB to 3.5 MB then back down to 1.5 MB and finally jumps to 4.74, where it stabilizes. The allocated memory for the Simulator is much more linear, with it climbing steady and quickly to around 2.35 MB where it stabilizes.
Another thing to note is the presence of 2.25 MB of allocated memory present on the device but not the Simulator from malloc and 700+ KB from CFNumber. As I am relatively new to using Instruments and profiling, I'm not exactly sure if this is normal. A quick Google search turned up nothing definitive. That 2.25 MB and 700 KB more than make up for the difference in memory allocation. To balance things, there are more entries for malloc with different amounts of memory present in the Simulator test not present in the device test.
Also, I found that when a second UIViewController is pushed onto the UINavigationController stack, allocated memory jumps to about 8.5-9 MB on the real device, but only about 4.5 to maybe 4.5 megabytes tops on the Simulator.
I know it is to be expected that the device would perform much differently from the Simulator, but should memory allocation not be pretty similar because the same code is being run on both devices? I would understand if this is a performance profiling, but for memory allocation, it seems that the numbers should be pretty similar. Can anyone shed some light as to whether this is normal or not?
This behavior is to be expected. Technically, when you run profiling with the simulator you are measuring stats based on your desktop's hardware. Even if you're just profiling allocations you can't expect them to work similarly because a lot of software optimizations/algorithms/etc are based on the hardware it's running on.
Unfortunately, Apple doesn't have an iOS emulator. You're better of profiling with the device though, as emulators tend to still be unreliable and slow (e.g. Android emulator).
You should always run leaks on an iOS device and never on the simulator. The results you get from the simulator will only serve as a distraction since they are rarely 100% accurate. You'll find yourself chasing down a lot of red herrings! hehehe
I know it is to be expected that the device would perform much
differently from the Simulator, but should memory allocation not be
pretty similar because the same code is being run on both devices? I
would understand if this is a performance profiling, but for memory
allocation, it seems that the numbers should be pretty similar. Can
anyone shed some light as to whether this is normal or not?
Technically the code is completely different. The simulator application compiles for x86 bytecode, while the device compiles for armv6/armv7.

iPhone Memory Usage Optimization / Performance Tuning

I am in the last phase of my iphone game development: optimization and performance tuning. My problem is, the game runs quite smooth on iphone 4 and iPad, but it often crashes on iPhone 2 with iOS 3.1.3 due to low memory.
I have gone through all the memory leak detection / clean up processes, and the Xcode instrument shows no leak except those from system library (see following screenshot). I also use "autorelease" rarely.
(bigger picture: click here)
I also profiled my application using "CPU Sampler" and "Allocations", but is a little confused by the result. This is the result from "Allocation" benchmark:
(bigger picture: click here)
This is the result after one game. As you can see, the "Live Bytes" is only 3.93MB, which shouldn't be a big deal (according to my understanding) -- but the game often crashes at this time on iPhone 2, ios 3.1.3 .
I also did a "CPU sampler" benchmark, following is the result:
(bigger picture: click here)
What confused me is, the real memory shows "22.32MB" and the virtual memory is more than 100MB, which is dramatically different from the result of "Allocation benchmark".
I am also confused by the fact that, my iPhone 3G, running iOS 4.1, even if it has almost exactly same hardware spec with iPhone 2, can run my game very well. It's slow and not as snappy, but it rarely crashs.
So my questions are:
What else I can do to identify the low memory issue on iphone 2?
Are the leaks from system libraries on the "Leaks" profiling result a problem?
Why "CPU sampler" and "Allocation" shows different memory foot print? Did I read them correctly?
Why iPhone 3G runs a lot more smoother than iPhone 2G? Is it because the newer iOS version (4.1 vs 3.1.3)?
1. What else I can do to identify the low memory issue on iphone 2?
Run your app in iOS simulator and use Hardware menu item "Simulate Memory Warning" item to trigger Out-Of-Memory events in places, which you suspect to crash.
Instrument your app in real device, but before launching it start as many other apps as possible to reduce amount of available memory. While running your app, switch every now and then back to app grid to (re)launch other apps. This way you will make system generate genuine Out-Of-Memory events, but you can't choose which app will receive them.
You could generate OOM events by yourself, but then you would be running a different application. Might be useful, while developing, but not recommended when close to release. Very annoying to debug bugs caused by debugging "helper" routines...
2. Are the leaks from system libraries on the "Leaks" profiling result a problem?
They could be side-effects of your code. Look around which part of your app might be starting that system service and whether you release / cancel / close everything.
3. Why "CPU sampler" and "Allocation" shows different memory foot print? Did I read them correctly?
No idea, but would like to know :)
4.Why iPhone 3G runs a lot more smoother than iPhone 2G? Is it because the newer iOS version (4.1 vs 3.1.3)?
iPhone 3G has better, faster and more hardware than iPhone2. As result, apps seem to run faster... which can be a problem, if your app runs too fast in faster hardware. Making sure your app runs "just right speed" regardless of hardware is a different question.

Memory Management/Instruments on the iPhone

I'm developing an RSS reader type iPhone application and it is nearing completion, however I upgraded to Xcode 4 with iOS 4.3 yesterday and I have run into some serious memory issues. My App now frequently gets memory warnings, I'm handling didReceiveMemoryWarning, and releasing all my cached images etc, but this does not provide a good user experience. I've also been using Instruments in an attempt to diagnose the problem, but this has been bringing up more questions then answers.
• Does the SDK 4.3 use more memory ? I wasn't receiving memory warnings before I upgraded. Not sure if this is relevant or not, but I'm doing most of my testing on an iPhone 3G with iOS 4.2 on it (4.3 is not supported on a 3G).
• Why does the allocations instrument tool live bytes column not match the real memory column in the activity monitor tool ? The activity monitor tool always reports more memory usage.
• According to leaks my app does not leak memory, in the simulator or on an actual iPhone, but when I look at allocations, it seems that as I transition between views and then pop views, the live bytes column does not return to its previous value, which is consistent with leaking memory ? (Yes subviews are released after they are popped)
• My app frequently reports a memory warning on startup, but only when I'm profiling the application with leaks. Does leaks cause extra memory overhead ?
• Perhaps this is a difficult question to answer, but what is a reasonable memory footprint for an iPhone app ? When I'm running leaks, my app will almost certainly be killed due to low memory a few minutes into being run, but allocations in the leaks tool reports I'm using less then 2 MB when the app is terminated.
• Why does the activity monitor instrument have a column for virtual memory ? Everything I've read states that the iPhone does not utilize virtual memory ?
The 4.3 SDK probably does use more memory, but if that's a question you're asking then you're probably on the wrong track, because as a developer that should not factor into how stable your app is.
I would not worry about the discrepancy between what Allocations reports and what Activity Monitor reports. It is also not unusual for the memory footprint to grow, as views are pushed and popped, and not shrink. Another answer on how free(3) works explains this phenomenon in better detail.
A reasonable memory footprint for an iOS app is the lowest amount your app needs in order to function.
iOS does indeed use virtual memory. From Apple's Memory Usage Performance Guidelines / About the Virtual Memory System:
Both Mac OS X and iOS include a fully-integrated virtual memory system that you cannot turn off; it is always on. Both system also provide up to 4 gigabytes of addressable space per 32-bit process.
...
Although Mac OS X supports a backing store, iOS does not. In iPhone applications, read-only data that is already on the disk (such as code pages) is simply removed from memory and reloaded from disk as needed. Writable data is never removed from memory by the operating system. Instead, if the amount of free memory drops below a certain threshold, the system asks the running applications to free up memory voluntarily to make room for new data. Applications that fail to free up enough memory are terminated.
I recommend you read through the whole document, especially Finding Memory Leaks. You can also use the Build-and-Analyze feature, which uses the built-in Clang to statically detect several kinds of bugs, including memory leaks.

How much memory is my iphone app using (from Simulator)

I know this has something to do with Instruments, but well it's kind of confusing and searching for Instruments on Google doesn't help much.
I'd like to know how well my app runs, like how much memory it uses. I just don't know where to find something like:
"As close as we can tell from the simulator you'll app will currently be using xx MBs of RAM on a real iphone device."
I need help on how to get this information.
You shouldn't test your memory usage in the simulator for a number of reasons, some of which are:
The simulator is running on your computer, not the phone, so the maximum amount of memory is the same as the amount of ram you have installed in your Mac.
The simulator, and your app when build with the simulator SDK, do not use the same libraries as they would on the device, and as a result, could use a different amount of memory.
However, if you can run on a device, you should use the Memory Monitor and Object Allocations instruments in Instruments to monitor your memory usage.
You should use the Run/With Performance Tools/Object Allocations. The graphs will show you the memory used.
And then you check the box "Created and Still Living" to know what objects are in memory.

How do I see how much memory my iPhone app is using?

How much real memory should my iphone app be using? What's going too high?
Keeping an eye on -(void)applicationDidReceiveMemoryWarning:(UIApplication *)application is definitely important, but if this is game, chances are the assets (notably textures presently on screen) can't simply be deallocated when that warning is received.
If you're a bit on the high side (20 MB +) I would recommend doing a bit of testing. Using Instruments and the Object Allocation tool (Run > Run with Performance Tool > Object Allocations) you can monitor how large your memory footprint gets. Then, try running Safari and fill the pages, then a few games and whatever else you can to get the memory higher, and see how your app performs.
In my testing for a recent release, 24 MB seemed to be pretty safe, and is a number I've heard elsewhere. Once you get above 30 or so MB, chances are your users will start having rare crashes (which happens to be the case for us, verified by crash reports). The higher you go, the more crashes users will see. There's no specific limit though, for the sake of testing I've pushed my app on an iPhone 3G up to 70 MB before, it just isn't likely to work for most, nor for long.
Requesting on the iTunes page that users restart their devices can help, though there's no guarantees it'll be effective.
Also, this is all assuming devices prior to the 3GS / 3rd Gen iPod Touch. If the app merely runs on an older device, it should have no problem on the newer ones (which have twice as much ram, 256 MB).
I think available memory may depend on several factors such as device model, how long it has not been rebooted etc.
You should not rely on some fixed values but instead try to use as little memory as possible and implement -(void)applicationDidReceiveMemoryWarning:(UIApplication *)application in your application delegate and/or -didReceiveMemoryWarning in your view controllers to handle low memory warnings there and free unused memory.