How to profile memory usage & performance with Instruments? - xcode

Of all the Instruments Trace Templates, I love using:
Zombies to detect where an object is getting over-released, great for debugging EXEC_BAD_ACCESS errors.
Leaks to detect memory leaks.
Core Animation w Color Blended Layers to detect frame rate & translucent subviews, great for smoothing up UITableView scrolling.
I always hear people saying to profile my app's memory usage & performance.
Why should I profile memory usage & performance? My app runs fine.
How do I do it?
I've used Allocations and see that my iPhone app starts at 1 MB total allocated memory and grows to 5 MB after normal usage. What is too high amount of memory usage on the iPhone? iPad? Mac?

To answer the whys, profiling memory usage is especially important for iOS apps because iPhones and iPads have much less RAM than Macs. The iPhone 4 has 512 MB of RAM, but earlier versions had 256 or 128 MB. Factor in the RAM the OS uses and multitasking, and your app doesn't have much RAM to waste so it's important to be aware of how much memory your app uses.
Profiling performance is something you usually do when your app is running slowly. Profile it to find the slow spots in your code so you can make the code run faster. If your app runs fine, you don't have much need to profile for performance.
To answer the hows, use the Allocations instrument to measure memory usage. The Live Bytes column in the All Allocations category tells you the amount of memory your app is currently using. The Allocations instrument's heapshot analysis measures memory growth in your app. Use the menu on the left side of the jump bar to do heapshot analysis.
The Time Profiler instrument profiles your app for performance. The difficult part of using the Time Profiler instrument is interpreting the results. The Time Profiler instrument isn't going to tell you your app spends 75% of its time in Function X. You have to dig through the data to find the slow spots in your code.
Regarding acceptable memory usage, it depends on the devices you want to support and the app. An app like Xcode using 100 MB of RAM would be OK, but an app like TextEdit using 100 MB for a one page document would be a problem. 5 MB shouldn't be a problem for an iOS app.

To address some of the comments in Mark's answer:
Allocations live bytes doesn't include OpenGL texture memory, which is used by CALayer/UIViews. This is the source of the disagreement with the Memory Monitor.
See the answer to this question here:
Understanding the memory consumption on iPhone

The memory really loaded into device's physical memory is the Resident Memory in VM Tracker Instrument.
Allocation Instrument only marks the memory created by malloc/[NSObject alloc] and some framework buffer, for example, decompressed image bitmap is not included in Allocation Instrument but it always takes most of your memory.
Please Watch WWDC 2012 Session 242 iOS App Performance: Memory to get the information from Apple.

Related

When smartband out of memory?

I have a smart band using nRF51822 chipset, they said it has 256kB/128kB flash + 32kB/16kB RAM, that's tiny memory, 2 days sync data is more than 5kB and it keep growing by time. I want to ask what happen if my device is out of memory ? Should I reset it and my data will lost ?
Thanks
To view the memory allocations of your app's profile, use the Memory Profiler component for Android Profiler that will help you identify memory leaks and memory churn that can lead to stutter, freezes, and even app crashes. It shows a realtime graph of your app's memory use, lets you capture a heap dump, force garbage collections, and track allocations.
There's no directly clear the storage for the app but you can just reset your watch factory settings and set it up again.

Xcode Memory Utilized

So in xcode, the Debug Navigator shows CPU Usage and Memory usage. When you click on Memory it says 'Memory Utilized'.
In my app I am using the latest Restkit (0.20.x) and every time I make a GET request using getObjectsAtPath (which doesn't even return a very large payload), the memory utilized increases about 2mb. So if I refresh my app 100 times, the Memory Utilized will have grown over 200mb.
However, when I run the Leaks tool, the Live Bytes remain fairly small and do not increase with each new request. Live bytes remains below 10mb the whole time.
So do I have a memory issue or not? Memory Utilized grows like crazy, but Live Bytes suggests everything is okay.
You can use Heapshot Analysis to evaluate the situation. If that shows no growth, then the memory consumption may be virtual memory which may (for example) reside in a cache/store which may support eviction and recreation -- so you should also identify growth in Virtual Memory regions.
If you keep making requests (e.g. try 200 refreshes), the memory will likely decrease at some point - or you will have memory warnings and ultimately allocation requests may fail. Determine how memory is reduced, if this is the case. Otherwise, you will need to determine where it is created and possibly referenced.
Also, test on a device in this case. The simulator is able to utilise much more memory than a device simply because it has more to work with. Memory constraints are not simulated.

What Instruments tools should I use to find out about my Monotouch app's memory usage?

I've been reading a lot about tracking memory usage in Instrument's but found little in combination with Monotouch.
There seem to be to three oposing claims here:
Use the Allocations utility of Instruments. The number of "live bytes" is the amount of physical memory used by the application.
Use the Memory Monitor plugin. From the list of processes, pick your app and check the "Real memory" column. That's the amount of RAM currently in use.
Use VM Tracker and make automatic snapshots. The "Dirty Size" if what you're after.
From what I've noticed:
"Real Memory" drops as soon as GC is triggered
Even if my "Live Bytes" remain around 30MB I will eventually catch memory warnings
With constant "Live Bytes", "Real Memory" can increase significantly and easily grow to 200MB or more.
While using QLPreviewController and viewing an insanly big Word document (1000 pages), scrolling through that document will grow real memory like crazy. If a memory warning is received, neither real memory, not live bytes drop at all. Eventually, the app will crash; Monotouch problem or Apple's problem?
Sometimes, real memory seems to grow and nothing can stop it. Then again, GC seems to clear big chunks of it. There is no real pattern in this.
So what is the correct answer? Is there exactly one?
EDIT: I attached two images. One showing memory usage in a stage in the middle of my app's life and the seconds one from way later. Both images reflect memory usage at the same point in the UI where nothing but two controllers are on screen. Maybe somebody can still comment what can be read from those number, especially the magic "Memory Tag 70".
Instruments is somewhat of a black box, but here is how I think it is:
There seem to be to three opposing claims here:
1. Use the *Allocation*s utility of Instruments. The number of "live bytes" is the amount of physical memory used by the application.
I don't know exactly what "Live Bytes" is, but it's not the amount of physical memory used by the application. I think it is the amount of physical memory used by all ObjectiveC objects (if this theory is correct "Live Bytes" does not contain any memory used by managed code, nor any memory used indirectly by ObjectiveC objects (such as image data), which seems to be true). "Live Bytes" is definitively useful if you want to track down leaked objects, but it's not (necessarily) a good indicator on how much memory is actually in use.
2 . Use the Memory Monitor plugin. From the list of processes, pick your app and check the "Real memory" column. That's the amount of RAM currently in use.
This is a bit closer: "Real Mem" is the amount of physical memory the app is using which isn't shared with other apps. The total amount of physical memory the app is using is "Virtual Mem", but big chunks of "Virtual Mem" is shared between apps (i.e. a shared library will of course use memory when it's loaded in memory, but since it's immutable it will only be loaded once for all processes. It will however be added to each process's "Virtual Mem", so if you add up the "Virtual Mem" used by all processes you will go way beyond the actual physical memory your device has).
3 . Use VM Tracker and make automatic snapshots. The "Dirty Size" if what you're after.
Correct. "Dirty Size" is what you're after - this is however closely related to "Real Mem", it's just "Real Mem" split into categories so you can easily see what's using the memory.
For the typical case of using a lot of memory due to leaking images, the process goes like this:
1. Verify with the Memory Monitor that your app really has a memory problem.
2. See in VM Tracker / "Dirty Size" that a lot of memory is used by image data (that's the magic "Memory Tag 70").
3. Use Allocations to find out where CGImages are created, see the corresponding stack trace and track down why those images aren't freed.
Each app is different though, so it's not possible to come up with a short recipe which works for all cases.
"Real Memory" drops as soon as GC is triggered
Even if my "Live Bytes" remain around 30MB I will eventually catch memory warnings
With constant "Live Bytes", "Real Memory" can increase significantly and easily grow to 200MB or more.
All these are explained above.
While using QLPreviewController and viewing an insanly big Word document (1000 pages), scrolling through that document will grow real memory like crazy. If a memory warning is received, neither real memory, not live bytes drop at all. Eventually, the app will crash; Monotouch problem or Apple's problem?
It could be your problem too :) It's impossible to tell without actually knowing where the memory goes.
Sometimes, real memory seems to grow and nothing can stop it. Then again, GC seems to clear big chunks of it. There is no real pattern in this.
You mean you're watching real memory grow while your app is doing absolutely nothing? If you're actually doing something in your app this is completely normal.

Xcode Instruments using lots of memory.

Okay so this is my issue and I apologize if its a duplicate. I searched but couldn't find anything I considered relevant.
When I run instruments from xcode and begin testing my application for memory leaks or allocations my iMac eventually begins to run very very slowly.
This caused me to run activity monitor while using instruments and I notice that every second instruments is open it takes up more and more real memory. Roughly 100MB's a sec.
It doesn't take long for it to consume all my iMacs free memory (2gbs) and then it starts to lag.
Anyways this doesn't occur with every application. I've done the same test with some application/projects I downloaded and instruments only seems to use about 250mbs of space and doesn't dramatically increase.
Is there something obvious that I'm doing incorrectly? Any help would be appreciated.
Thanks.
instruments consumes a lot of memory.
depending on what you are recording, you may reduce its memory usage. for example, you can often specify what (or what not) to record, or lower sampling frequencies(if applicable).
100MB/s is unusually high. can you give a more exact description of what you are recording in that time? (instruments you use, what the process you record is doing, etc).
Xcode 3 used a lot less memory - not sure if that's also the case for Instruments.
You can reduce the memory usage somewhat by running the toolset as 32 bit processes.
lastly, 2GB physical memory is nothing for Xcode + Instruments + iOS Sim. fwiw, i regularly exhaust physical memory with 8 or more GB. boo. fortunately, memory is cheap when you want 4 or 8GB.
Update
I tried using instruments for Allocations, Leaks and Zombies
You can run these tests individually, if you must.
Allocations
By itself, allocations should not consume a ton of memory if your app is not creating a lot of allocations.
To reduce memory with this instrument, you can disable some options you are not interested in:
do not record each ref count operation
only track active allocs
disable zombie detection
do not identify c++ objects
Leaks
implies Allocations instrument only if you want history of leaks.
Leaks detection itself can consume a lot of memory because it scans memory, basically cloning your allocations. say you have 100MB allocated - leaks will periodically pause the process, clone the memory and scan it for patterns. this could consume more memory than your app. iirc, it's executed as a subprocess in instruments.
Zombies
implies Allocations instrument.
Zombie detection usually implies ref count recording. When debugging zombies, it's most effective to never free them. If you do free them, you may only detect transient zombies (not sure if there's an option for that in instruments...). Never freeing objc allocations will obviously consume more memory. Running leaks on a process will then consume more memory because your heap sizes will be larger - leaks and zombies should not be combined.
you should be able to reduce total consumption by disabling some of these options and testing for them individually.
Notes
The bleeding edge Developer Tools releases can be really shaky. If you are having problems, it helps to stick to the official releases.
I can run a osx unit test (primarily c/c++ apis) with allocations alone, it consumes about 1MB/s when recording. something seems wrong, but perhaps that indicates an issue in your program (many transient allocations?).
changing the way the data is displayed and/or the charge/focus settings can require a lot of memory. e.g. "Restore All" can require a few GB to process a large sample.
if 100MB/s is an accurate number, i'd file a bug. I know Instruments consumes a lot of memory, but that's very high for recording an idle app, even with the expectation that instruments consumes a lot of memory.
good luck

What isĀ "dirty" memory in Instruments?

When I monitor my application using instruments and the instrument "allocations" I see a big amount of memory being marked as "dirty". What does that mean? I have no memory leaks in my application yet this pile of "dirty" memory keeps increasing.
Dirty is a computer term used to denote cached data that needs to be sync'ed with the main memory. Don't worry, since this is automatically done by the hardware.
"...I am trying to find out what is using up all my memory."
The WWDC 2010 Session 311 presentation, Advanced Memory Analysis with Instruments, includes a section on 'Responding to Memory Warnings' (at ~38:40 in the video) with a demo that illustrates how to find "resident, dirty memory" with the Instruments VM Tracker and one way to flush it.

Resources