iOS questions about Instruments tool, memory issue in my app - ios

I just started learning the instruments tool, and I'm pretty sure what I am seeing is not good. When I look at allocations, specifically the column "Live Bytes" and "Overall Bytes", I see the number continually increases as the app runs...
My app has two view controllers. A table view, and the second view controller displays detailed information about the row they selected in the table view, downloaded from the internet.
I kept clicking a row in the table view, followed by clicking the back button in the navigation bar... and LiveBytes continued to increase.
I'm guessing this means that my objects aren't being released from memory... but please correct me if I'm wrong.
MY QUESTION IS: How do I use the data in instruments/allocations to track down this memory issue? How do I find the objects not being released from memory?
I'm looking for tips on how to use these tools to clean up any memory problems my app has.
Thanks!
XCODE 4.2.1, deploying to iOS 5.0+
EDIT: I'm looking at the #living column and seeing objects like UIScrollView continuously increase... and never decrease. When I click the back button in a navigation bar, are objects automatically released from memory? When are objects released, or do I need to do it manually? Or could I be running into an issue due to using strong pointers, causing objects to not be released?

Whenever you want to observe memory usage in a cyclic pattern, there's the wonderful Heapshot analysis in the "Allocations" instrument.
Start your app and go to a default state.
In Instruments, press the "Mark Heap" button to create the "Baseline".
Do something in your app like pushing a view controller.
Return to the default state.
Press the "Mark Heap" button again to create a heapshot.
Repeat about five times from step 3.
This will result in a list of heapshots, each showing the objects that are still alive from that cycle. If your app has no leaks there will be no objects left in the middle heapshots.
The first one or two cycles might have warmed up some caches, the last two might not have cleaned up some reused resources. That's why it's usually a good idea to make four to six heapshots.
The magic in the heapshot analysis lies in the fact that the heapshots show you the leaked objects from previous cycles and remove them automatically when the objects are released later. In contrary to the "Leaks" instrument it also finds abandoned memory, not only leaks.

Most Probably you have discarded the arm64 and are running your app with armv7 only. Add both arm64 and armv7 as architectures

I think one of the best ways to solve memory issues is to use ARC.
Edit -> Refactor -> Upgrade to Objective-C ARC.
ARC will handle the majority of memory management in your app. Especially sice your app doesn't sound too complex, it might totally eliminate your problem. You still need to watch out for retain cycles and listen to memory warnings though. If you don't want to use ARC (which you should) at least run the static analyzer. Your problem might be something simple that the static analyzer can show you how to fix.
Edit:
You mentioned scroll views- this might be your problem: Memory leak every time UIScrollView is released

The profile tool has an instrument called 'Leaks'. It is similar to the 'Allocations' instrument but it shows you the object that was not released. May be you can use the 'Leaks' tool to find what is the object that was retained and release these object.

Related

iOS Memory usage keep increasing

I'm new to iOS development.
I'm building a simple bus schedule app that makes a HTTP request, parse XML, and display/save data. I have four table view controllers and two view controllers.
When I start the app, Xcode memory report tells me that its memory usage is ~18MB, which is weird since it's just a simple app. I've looked at similar apps on the app store but they were all less than 10MB. Since it's a bus schedule app, I have it make new requests every 30 seconds to update the time. I noticed that each time I change view to look at another schedule, the memory usage increases and it may go up to 50MB or more.
I looked at Xcode's instrument and it looked like there was no leaks. I also looked at allocations and it looked like live bytes kept increasing every time I switched views.
I am kinda stuck from what to do from here. Can anyone guide me please? Thanks in advance.
Use Heapshot to find memory creep. (see: bbum blog)
Basically, their method is to run the Instruments allocate tool, take a heapshot, run an iteration of your code and another heapshot, repeating 3 or 4 times. This will indicate memory that is allocated and not released during the iterations.
In this case, take a heapshot (called something different now) between downloads.
To figure out the results, disclose to see the individual allocations.
If you need to see where retains, releases, and autoreleases occur for an object use Instruments:
Run in Instruments, in Allocations set "Record reference counts" to on (you will have to stop recording to set the option). Allow the problem code to run, stop recording, then search for the object of interest. After that, you'll need to drill down and you will be able to see where all retains, releases and autoreleases occurred.
First, take a look at heap shots as #Zaph suggested. Well worth your while in terms of seeing what's being allocated and not released.
Another technique I use is to use instruments filtering options to filter the display for just the classes in my app. Then, I look for classes which have unusual number's of living instances. For example, most view controllers usually have only one active instance. If there are more, then something is retaining them. Blocks and notification listeners are often the cause.
In your example screen shot, I noticed two things that I would investigate.
Firstly, you have 365 living core animations taking some 30M. Not sure why, but worth thinking about.
Secondly, near the bottom, I noticed 166 table view cell scroll views. Sounds like a lot. I can't see how many living table view controllers you have, but I'm wondering if they are not reallocing. Filtering this list will help establish what's not being dealloc'd.
Finally, leaks can be useful in finding issues, but most of the time what we would regard as a leak looks ok to instruments. So, looking at memory and numbers of allocated instances is a far better guide to finding where things are not being dealloc'd.
Hard to say without any code, but it looks like you have a retain cycle somewhere.
Try to add a dealloc method to the view controllers and make sure that you enter it whenever the view controller disappears.
You say that you make a new request every 30 seconds. If you use a timer with the view controller as a target, the timer has a strong reference to the view controller and vice versa. You have to invalidate the timer when your view controller disappears.

resident memeory keeps increasing

I am having issue with memory management. I am using arc. I tried setting arrays, oulet to nil in viewdidunload and try the same in dealloc methods.
When I use instruments it does not show any thing, I tried finding resident memory using this link
Programmatically retrieve memory usage on iPhone
I have two uitableviewcontrollers added as subview on view when I click on left table other table refreshes.
Each time I tap on a table and refresh the right one, the resident memory is increasing by 2MB.
I am removing all the objects but still it keeps increasing.
Does any one have an idea how to proceed. I know nothing can be told with out code. I am looking for guideline of what could be the possible culprit.
Thanks
Use heap shot analysis.
1) Go to screen
2) Mark heap
3) Tap and refresh table
4) Mark heap
5) Review Heap shot results
You may want to perform this sample or sequence a few times to understand the growth better.
Here's a great write up by bbum: http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/
You might also consider reviewing your Cycles and Roots, also using the Leaks Instrument.

UIWebView memory leak

I have an iPad app (IOS 4.3 & 5.0) that is creating a UIView with at least 2 subviews every time the user pages forward or backward. The 2 subviews are UIWebView objects.
On every relevant swipe the old UIWebViews are removed and deallocated properly (removeFromSuperview then stopLoading and set delegate to nil) and the parent UIView is deallocated. I can confirm that both parent UIView and the 2 child UIWebViews are absolutely gone.
I can see the retain count on the webviews as they are being removed and I am quite sure that they are indeed removed every time.
However my memory allocation continues to increase on every swipe by ~200-350k . No leaks in instrument but I can see the memory usage going up slowly.
On iPad 1 the app eventually (within 6-10 minutes of moderate usage) receives multiple memory warnings and is terminated. LowMemory crash log...etc is generated.
We use stringByEvaluatingJavaScriptFromString and loadRequest to populate the Webviews. Memory usage creeps up even when nothing is injected or loaded into the webViews.
Is anybody experiencing this kind of behavior with UIWebViews ? Has anyone dealt with this successfully ?
Thoughs, comments & answers would be greatly appreciated.
Try to use Instruments but with the "Allocations" template and watch the "# Living" columns for UIWebView. I usually use it like this:
Profile app with Allocations template
"Warn up" the app by going thru all tabs, scroll around etc.
Press "Mark Heap", this will create a "Baseline" heapshot
Do the thing you think causes objects to stay around
Press "Mark Heap" again, this will create a "Heapshop #" heapshot
Inspect the objects in "Heapshop #" which will show size and number of objects created and alive since the last heapshot.
Goto 4
Not aware of any leak, but if you are destroying and re-creating the same view hierarchy every swipe, why not store the views and re-use them instead?
Regardless of whether they leak, webviews are computationally expensive to set up, so re-using them and just reloading the content should give you a performance boost, and may solve your leak as well.
are you still seeing this issue? I traced something which looks like unbounded memory usage (not necessarily a leak, but I get low memory warnings and eventual process termination) by calling stringByEvaluatingJavaScriptFromString over and over:
[webview stringByEvaluatingJavaScriptFromString:#"something()"];
It seems like there is something odd there.

iOS allocations - persistent count in heapshots not always 0

While profiling my iOS app I perform a simple task multiple times where I push and pop a view from the stack, and then take a heapshot. The same code is executed each time and the pushed view just contains some images which get removed as soon as the view gets popped.
Now because the persistent count is 0 for almost half of the heapshots, would it be safe to assume there is no abandoned memory?
I've heard that the rows with a persistent count greater than zero could be because of some internal caching.
I am using Xcode 4.2.1 and the app is using ARC.
Edit:
Thanks to Kendall Helmstetter Gelner I've managed to debug this problem further. I probably shouldn't have been using the simulator for debugging this. I've now run it on the device and it now looks like there is one object which isn't getting released:
After looking through the extended detail view I think I've just about found the cause of the problem.
It's hard to say from just that screenshot what might be cached or not - UIImage will cache things, possibly some other system elements too. It looks like you might be running that in the simulator, have you tried heapshot on a device?
You could also select "Hide System Libraries" to the side and get a better idea how much of your own code is involved.

Understanding responsible callers in Instruments Results for Alloc

I am using instruments to pindown on what is consuming more memory. I always get the Living bytes and overall bytes to be same. I believe not much deallocation has happened in my code. And this is a bad sign.
When I go and find the responsible caller and track down what it is, I could not find it. The responsible callers are _dydldstart and NSStringFromClass.
Is this behaviour normal ? How can check the exact responsible caller?
The cause of the Living Bytes and Overall Bytes columns being the same is most likely that Instruments is tracking only active allocations. If you want Instruments to track everything, click the Info button next to the Allocations instrument in the instrument list and deselect the Only track active allocations checkbox.
Opening the extended detail view shows the call stack for your memory allocations, which will make it easier to find the exact responsible caller. Choose View > Extended Detail to open the extended detail view.
The call tree view can also help you determine where you are allocating memory in your code. Use the jump bar to switch to the call tree view.
"I always get the Living bytes and overall bytes to be same".
I had this problem only because I was setting up NSZombieEnabled as environment variables when I was testing my App in Instruments. After disabling that variable, the problem had gone.
NSZombieEnabled I think does not let any variables to be released.
I am not sure if removing NSZombieEnabled solved the probelm.
I was actually using Allocations in two different ways. Only when used with Leaks Tool, I had the problem.
Another question of Mine is an answer to this question:
Ambiguities in using Instruments for iOS Development

Resources