There is an item details screen where user can read all info about a selected item, and there is also an search bar in this screen where user can search for items then when they choose one, it will be displayed, because of complexity data, so I have to do this by pop current item view then push a new item view in.
Everything is ok when do this just some times, the problem happens when user do this about 25-30 times, app become slowly then crashes.
I guess that the should be a problem with memory but could not find out where it is.
Please help me on this, thanks!
You have to find out where your memory grows. Then and only then you can find how to fix it. I'll give you few tips,
Go to Xcode -> Product -> Analyze to find out what are the places you're having memory leaks and avoid them.
Do more tests with Instruments also.
Don't allocate big images using,
[UIImage imageNamed:];
above method will cache the image. Instead use,
[UIImage imageWithContentsOfFile:];
Related
When will i have running my app in simulator. xCode debug section shows cpu and memory section it will display some graph flow. but i don't know what is that.
My question is,
what is that cpu and memory graph
when i running my app the memory increase towards when ever i navigate to any other viewcontroller and return back same or other viewcontroller etc., it always increase the memory size.
why it occurs. Is that any problem. if yes how to fix that and why i caused.
Here below image i navigated to any other view controller. it is suddenly increase from above image memory size to below image memory size.
Well from overall memory consumption it would seem as if you are handling some images or videos or other heavy content. Many make memory leaks handling those. To test if thats a real leak, you can do so:
Go to some page A (any page), from there go to some other page B, then back to A, back to B.. repeat that and if your memory is really getting high - you have a leak.
BUT bear in mind: These graphs show you how much resources your app use from your device, you SHOULD NOT use that to find leaks. Instead go to profiler, choose memory leaks and use that. If you are using ARC and cannot find any leaks, you can use "mark heap" button in allocations instrument to find memory build ups like this: Repeat the "page A page B" cycle and every time you are in page A, press "mark heap" button. You will now see generations which each show how much memory has increased from last generation. If it always keeps increasing same amount - double clicking generation will show you all the places that you have possible leaks.
Additional info: Easiest way to profile your app is to hold left mouse on "play" button in xcode until more buttons pop-up. Choose profile. When instruments appear - choose "Leaks".
From there - you should be able to see overall statistics of your app. I will not go in detail about profiler, because all the info is already available in the net. For example: https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Introduction/Introduction.html
I have an iPad app which is crashing on iPad (First model) as it is running out of memory.
In the app I have a main view which adds as subviews about 20 UIScrollViews (custom class) each containing a UIImageView and UIImage. When the user moves to the next page, I remove all these subviews from the superview and then add 20 new UIScrollViews to the same view.
If I profile the app for allocations and memory leaks everything is ok - the memory allocated stays at about 2MB while the user scrolls left and right.
However if I look at the real memory usage in the Activity Monitor I can see that every time the user moves to a new page, the real memory increases by about 20MB. Eventually after a few new pages the app size hits 150+ MB and crashes.
Can anyone suggest what might cause this type of behaviour and how I can further troubleshoot this ?
Just a bit more info on the app structure :
In view did load the images are loaded into an NSMutableArray using initWithContentsOfFile.
You should not be maintaining these images in an array. Images consume a disproportionate amount of your limited RAM. There are a couple of approaches:
If you want to keep it simple, just don't store the images anywhere. Load the image property of the UIImageView by loading the image via initWithContentsOfFile and call it a day.
If you want some RAM caching for performance reasons, you could use imageNamed instead of initWithContentsOfFile. When the app receives a memory warning, the cache will automatically be purged.
I'd be inclined to use initWithContentsOfFile, but then manually cache in my own NSCache (which is like a NSDictionary, except you can set a countLimit of how many images it should hang on to).
By the way, you don't describe what technically happens when "the user moves to the next page." If you're simply refreshing the existing controls on the existing view controller, then everything is probably fine (once you fix the NSMutableArray problem I discuss above). If you're pushing/presenting to another view controller or scrolling controls off screen but neglecting to remove the old ones from their superview, then that will also cause problems. You might want to clarify what you're doing there.
Bottom line, you just need to make sure that when you go from one page to another, that you're not maintaining strong references to any old images or controls.
I just started working on a relatively complex project, and have discovered a bug. When the user logs out, the view controllers are still allocated behind the login view controller. They continue responding to rotation events, etc. I have set the controller to nil upon logout, but it's still responding, which indicates that some other object still has a pointer to it. (This project has ARC enabled.)
Pre-ARC I could likely solve this by overriding retain:
- (id) retain
{
// Break here to see who is retaining me.
return [super retain];
}
How can I use the Xcode debugging tools to select an object and list all the other objects that point to it? Is there a better approach than simply hunting through all the code?
As of Xcode 8 you can use the Debug Memory Graph:
Run your app and look at the navigator at the bottom of the screen. You should see a set of three connected circles:
Navigate to wherever so that your object is allocated in memory and then tap on this icon. It should pause your app and a graph should pop up on your Xcode screen. Now, on the left side of the screen you can see a list of objects. Find the object you want to see all the pointers to and click on it. Now they should be visible in the graph. You can expand these branches by tapping on the two arrows on the nodes at the left end of the branch. The graph should look something like this:
This saved me literally days of work. It's an extremely useful tool. I hope it helps someone else too.
The Instruments Heapshot Analysis tool was the best thing I could find for this purpose. This article provides a more complete tutorial, but the basic steps are:
Select Product -> Profile. Choose the Allocations Instrument.
On the left, press the Mark Heap button before/after significant events. In my case, this was before login, after login, and after logout.
Search through the Heapshot for the class you're looking for.
Press the disclosure triangle to see its memory address(es).
Press the arrow to the right of a memory address to see its responsible caller (it appears in the rightmost column.)
If someone else writes up a more thorough explanation, or can offer any related lldb commands, I'm happy to mark your answer as correct.
I am quite beginner in development and I'm making an application that have about 150 ViewControllers ! Each one have a UIImageView.
I've been doing a bit of testing, and after a use the app for a while on the iPhone itself, it Crashes when I keep viewing the ViewControllers.
I've been analyzing this in instruments, and I have no leaks, however my memory allocation just goes up and up and when I keep viewing the ViewControllers on my iPhone the usage just goes up and up until a crash.
I think it's clear that it's crashing because the app is simply taking up too much memory.
So could any one explain how to release viewControllers in order to free up the memory so there will be no crash
Thanks in advance !
The first question you need to ask yourself is why do you need 150 ViewControllers.
Do you want to present 150 different images?
If so, then multiple ViewControllers is not the way to go. You probably need to use a UIScrollView that will contain your images (not all of them at once, of course. Use lazy loading).
What's probably happening in your case is that you call "pushViewController" each time you need to display a new ViewController, but this doesn't release the previous ViewController. It simply stacks all of the previous ViewControllers and retains their pointers.
You see, the way Navigation Controllers work is that they have an array of view controllers. Every time you present a new view controller, it is added at the end of the array. When you click on "Back" or call "popViewController" the last item of the array is removed (and then released automatically from memory).
See this and this questions to learn how to create a UIScrollView to scroll images.
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.