My app works fine on the simulator but it crashes on a device after playing with it for some time. I get an error message regarding memory a few times at Level 1 and then sometime at level 2 before crashing.
Received memory warning. Level=1
I used instruments to investigate and found that there were no leaks in my program but the memory allocation keeps going up. I am using multiple view controllers and as I move from one view controller, I never see the memory allocation go down. I tested by adding an empty view controller with only one back button and when I went back and forth between the main view and this empty view it crashed after a certain number of clicks.
I am attaching a picture of the analysis from instruments.
I have tried many things. I am using UIImage view and I have replaced the imageNamed method to withContentOfFile method but that didn't solve the problem.
Very frustrated with this memory issue. What is the next step in troubleshooting this?
My app works fine on the simulator but it crashes on a device after playing with it for some time. I get an error message regarding memory a few times at Level 1 and then sometime at level 2 before crashing.
Received memory warning. Level=1
I used instruments to investigate and found that there were no leaks in my program but the memory allocation keeps going up. I am using multiple view controllers and as I move from one view controller, I never see the memory allocation go down. I tested by adding an empty view controller with only one back button and when I went back and forth between the main view and this empty view it crashed after a certain number of clicks.
I am attaching a picture of the analysis from instruments.
I have tried many things. I am using UIImage view and I have replaced the imageNamed method to withContentOfFile method but that didn't solve the problem.
Very frustrated with this memory issue. What is the next step in troubleshooting this?
Many thanks.
N
Have you cleaned your code and run build and analyze on it?
The memory profile you posted (I could see it for once!) does suggest a memory leak to me.
Note that you can do things like add pointers to objects to an NSArray that prevents them from being released. That doesn't meet the strict definition of a leak, but it does mean that you don't release things when you are done with them. I would suggest looking at the allocations tool and looking at the types of objects that you are creating, by number and by size. That should let you figure out what sorts of objects are being created and filling up memory. Then if the automated tools can't find anything, you'll need to wade through your code yourself. Do small tests where you exercise a bit of your app, then close it and go back to your starting point.
One question: Does the memory use climb on the simulator like it does on the device? If so, you can still use the simulator to track down the problem. Run on the simulator with the allocs instrument and watch total allocations. Do simple things like opening a new view controller and then closing it, then forcing a memory warning. After a memory warning, your app should revert it's previous memory use.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.
I have a tab bar controller with 4 tabs. All the tabs have navigation controllers. My application is full of views. I am having exact the same behavior in the allocations. It is accumulating and building up and I didn’t know that this suggests memory leak. I am now trying to fix the issues in my application.
I would like to ask you guys some questions. I hope you can help me with them. I know this is bit too long but I think you can answer them quickly.
1. First of all I would like to learn how the allocation graph should look like. I assume it should be moving up and down rather than building up?? Is this right??
2. Duncan, you said we can trace the leaking variables by checking them out from the allocation tool. I have names like Malloc 16 Bytes, Malloc 32 Bytes, CFString (is this NSString?), CFBasicHash(value-store), CFUtilities, CFArray, _NSArrayI and many more. How can we use these to determine the leaking variables?
Initially I tried to release "path" which I knew was wrong. When I Build and Analyze it gave error:
"Incorrect decrement of the reference count of an object that is not owned at this point by the caller
1. Method returns an Objective-C object with a +0 retain count (non-owning reference)
2 Incorrect decrement of the reference count of an object that is not owned at this point by the caller"
However, when I check its retain count right after its declaration and initialization path has a retain count of 1. Then I tried path = nil; and checked the retain count, it returned 0. I should always have the retain count to be 0 when I am done with variable?? Is it right to use nil here?
After the declaration and initialization of array the retain count is 1. After self.content = array both array and content have retain count of 2. After [array release] array retain count is 1 and so is self.content's.After array = nil; array returns 0 and content returns 1. Is this how it should be??
5. In a navigation controller, should I load the views in -tableView: didSelectRowAtIndexPath according to the selected row. OR should I load every view to an array of views in the viewDidLoad and the extract the desired one in -tableView: didSelectRowAtIndexPath.
child1, child2 and child3 are 1,5 and 0 respectively. Why is the retainCount 5 after the pushViewController method? Is this something usual or is there mistake I am missing? Is it right to use nil??
My concern is setting it to "nil" does not call the dealloc method by "release" does. When the retain count is 5, setting it to nil causes a leak? Logically the release should be called on the object 5 times to release all the instance variables?? Is this right??
I will strongly appreciate if anyone please gives me a hand.
7. The FirstLevelViewControllers of the navigation controllers of the tabs are never released. right?
From the questions you're asking, it's pretty clear you don't understand how to handle memory management in Cocoa. You need to stop and read the memory management programming guide in the Xcode docs. Do a search on "Memory Management Policy", and read the article with that title that comes up.
Quote:
Originally Posted by denin
Hello,
I have a tab bar controller with 4 tabs. All the tabs have navigation controllers. My application is full of views. I am having exact the same behavior in the allocations. It is accumulating and building up and I didn’t know that this suggests memory leak. I am now trying to fix the issues in my application.
I would like to ask you guys some questions. I hope you can help me with them. I know this is bit too long but I think you can answer them quickly.
1. First of all I would like to learn how the allocation graph should look like. I assume it should be moving up and down rather than building up?? Is this right??
Right. Unless you are doing something that adds more content to your program (like recording more of your voice into a voice recorder, or adding text to a word processor) your app's memory should bounce around, but not increase steadily.
Quote:
2. Duncan, you said we can trace the leaking variables by checking them out from the allocation tool. I have names like Malloc 16 Bytes, Malloc 32 Bytes, CFString (is this NSString?), CFBasicHash(value-store), CFUtilities, CFArray, _NSArrayI and many more. How can we use these to determine the leaking variables?
I'm not an expert at using instruments. I'm ok at using it, but don't know how to describe it. I'd suggest watching the videos from Apple's developer conference on the subject. I think they covered it in 2010?
Initially I tried to release "path" which I knew was wrong. When I Build and Analyze it gave error:
"Incorrect decrement of the reference count of an object that is not owned at this point by the caller
1. Method returns an Objective-C object with a +0 retain count (non-owning reference)
2 Incorrect decrement of the reference count of an object that is not owned at this point by the caller"
Read the docs I referenced. You should only release objects that you create using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy. All other methods return objects that you do not own, and should not release.
Quote:
However, when I check its retain count right after its declaration and initialization path has a retain count of 1.
You can't get meaningful information from the retain count on objects. If an object is autoreleased, it could have a positive retain count, but still be released in the near future. Learn the memory management rules and follow them consistently.
Quote:
Then I tried path = nil; and checked the retain count, it returned 0. I should always have the retain count to be 0 when I am done with variable?? Is it right to use nil here?
Think about that for a second.
If you set path to nil, how can you check the retain count after? You don't have a pointer to the path any more.
After the declaration and initialization of array the retain count is 1. After self.content = array both array and content have retain count of 2. After [array release] array retain count is 1 and so is self.content's.After array = nil; array returns 0 and content returns 1. Is this how it should be??
5. In a navigation controller, should I load the views in -tableView: didSelectRowAtIndexPath according to the selected row. OR should I load every view to an array of views in the viewDidLoad and the extract the desired one in -tableView: didSelectRowAtIndexPath.
child1, child2 and child3 are 1,5 and 0 respectively. Why is the retainCount 5 after the pushViewController method? Is this something usual or is there mistake I am missing? Is it right to use nil??
My concern is setting it to "nil" does not call the dealloc method by "release" does. When the retain count is 5, setting it to nil causes a leak? Logically the release should be called on the object 5 times to release all the instance variables?? Is this right??
I will strongly appreciate if anyone please gives me a hand.
7. The FirstLevelViewControllers of the navigation controllers of the tabs are never released. right?
Setting a variable to nil has no effect on it's retain count. It just sets your local pointer to nil. Then, when you try to check the retain count, you check a nil's retain count, which always returns zero.
As I say, don't try to read retain counts. It will only confuse you. Learn the memory management rules and follow them, and you'll be okay.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.