NSAutoReleasePool appears not be working - iphone

I am writing an iPhone app that starts taking up memory as soon as it starts and just keeps taking up more memory. The reason appears to be that I've included a tight inner loop in that I'd like to run for a long while. Dont' worry, it's not supposed to be part of the user interactive app, it's just for testing the internal code.
In any case, by searching stackoverflow I found out that I should use my own NSAutoReleasePool because the main one is not getting reached. Also, I found that I should eschew use of autorelease. I've done both of these things, although I haven't been able to get rid of all autorelease calls. These do not fix the problem, however. Now my number of allocations (as per the instruments Allocations tool) travels in a triangle wave pattern, presumably because of the pool draining, but the number of allocations and the overall bytes creeps ever upwards. This increase in memory usage is also reflected in activity monitor. The objects that are getting allocated fall under all sorts of types including Malloc, CFString, NSConcreteMutableData; basically many core library classes and many of my code's objects.
This is basically what I'm doing:
for (int i=0; i<1000; i++) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
... do lots of stuff
[pool drain];
}
Any ideas why this is happening? I don't have any memory leaks according to the Leaks instrument and I don't have NSZombieEnabled set or any other arguments for that matter.
Thanks
UPDATE:
I just noticed some memory leaks are getting found when I use the auto release pool that aren't there when I'm not use the pool. Strange... Maybe that helps point towards the problem. I'm trying to track those leaks down now but so far they don't look like leaks in my code, but they make sense if the pool isn't actually releasing them.
UPDATE:
Ok, figured it out and it was caused by a few things. First, I was not properly releasing objects that contained references to each other so these never ended up getting released. Second, there are still memory leaks but these are in the foundation classes. I found an answer somewhere suggesting that this was not surprising, especially when running in the Simulator so I'm not going to worry about it too much. Hopefully this is useful to someone.

This can be caused by certain system caching, i.e. ImageNamed and certain URL calls will actually be cached by the system and are therefore not leaks but also nothing that you can release manually. There are normally better ways to handle such things for example creating your own image caching which you can clear...

Related

iOS - Is there a way to trigger the memory cleaning?

I found that (for example) a UI object, like UIPickerView, is allocated and release frequently, even the corresponding dealloc method is called (proved by using Instruments), the Heap still grows up.
Is there a way to trigger the optimization of the autorelease pool to improve the whole scenario ?
My application needs to take photo, manage photo and upload to server. Over period of time, the Heap grows large and finally it crashes my application. ** I checked that there is no obvious memory leakage * with the use of Instruments.
Any Help or suggestion ?
Thanks.
You can create your own autorelease pool at places which make sense to your application. The following way of creating autorelease pools works with or without ARC.
// Stuff you plan to keep around after finishing the block below
#autoreleasepool {
// Load an image, send to server
}
// The images are released
It sounds like it is taking some time for your memory to get out of hand. If you are doing your work in the main UI run loop you should have autorelease occurring very regularly, so I'm not sure that another autorelease pool will help you. Perhaps you are keeping your references in such a way that they are not being released because they could still be used. Many leaks occur because objects are not removed from arrays, sets, and dictionaries.

Using Instruments for Memory Leak Checking in XCode?

Good Day,
I'm completely inexperienced in checking for memory leaks and so any help with this would be great.
I've just finished the bulk of the work for my iPhone app and I'm now trying to figure out why it stops working after a couple of runs. Using Instruments in Leaks and Allocations mode I can see there are two objects that are piling up memory quite quickly and not releasing:
I'm not a hundred percent sure where or why this is happening, but when I clicked on the arrow to the right of UIDeviceRGBColor the Responsible Caller is stated as
[UIColor allocWithZone];
I did a search through my project for UIColor and came up this (take note of _colorThreshold):
I believe my problem has to do with _colorThreshold which doesn't seem to be getting released:
I've tried adding autorelease to their initialisation arguments, but that made the app crash. Any advice here?
EDIT 1
Here is the screen shot from LevelMeter.h
There are several issues with the above:
Is LevelMeterColorThreshold an Objective-C class?
If so, why are you using malloc instead of the usual alloc/init?
As you pasted screenshots of your search results, we cannot see the surrounding code, as only lines with search hits are displayed.
Does the Leaks instrument report leaks, or are you just allocating unnecessary memory?
There is a difference between those two cases:
A leak happens if you loose reference to an object so that you cannot send it a release message later.
Instantiating objects, that aren't needed anymore without releasing/freeing them
Leaks can only detect the first case.
Sample for a leak:
NSMutableString* test = [[NSMutableString alloc] initWithString:#"1"];
NSLog(#"%#", test);
NSMutableString* anotherTest = [[NSMutableString alloc] initWithString:#"2"];
test = anotherTest; //here we loose reference to the original object
NSLog(#"%#", test);
By assigning anotherTest to test, we have lost the reference that points to the memory address that contains #"1".

Memory crashes in iOS with real memory usage only at 5megs

I have been hunting down memory leaks for some time in my app. As of right now, as I flip back and forth between two views while watching the memory monitor instrument, the real memory fluctuates between 5 and 6 megs. This is all fine -- as far as I can tell everything is getting released properly when I pop back off a view. However, the virtual memory continues to increase and my available real memory drops rapidly every time I push the view back onto the view stack (even though the real memory usage of the app isn't increasing). Eventually, this all leads to an out of memory crash. Is this a telltale sign of any specific issue, or am I just missing a memory leak somewhere?
EDIT: The odd part is, I get an out of memory crash while the app is still only using up about 5 megs of real memory.
Do not use -retainCount.
The absolute retain count of an object is meaningless. It is an implementation detail. It may be influenced by many factors well beyond your code.
You should call release exactly same number of times that you caused the object to be retained. No less (unless you like leaks) and, certainly, no more (unless you like crashes).
See the Memory Management Guidelines for full details.
In this specific case, you are leaking memory but in a way that leaks can't find it. The objects that are leaked are still connected to your overall application's object graph somehow. Maybe through a notification, maybe through delegation, doesn't matter -- leaks sees the reference and concludes that the object might still be live.
Use the Allocations Instrument. Configure it to only track live allocations (since you don't care about objects that have been deallocated). Do some stuff with your app. Check out what Allocations knows about and explain why all those objects should stick around. You can use the data mining facilities to filter down to just your objects.
Anyway, you can also use the "Build -> Build and analyze" option to find suspicious non-conventional code.
Another reason why you may have memory lost in lower API layers is if you don't remove all your views from your view hierarchy (aka : not calling [view removeFromSuperview] everywhere). At least that's what seemed to have happened to me.
Note that most of time this isn't required, as you would simply release the main view and all its subviews, then rebuild it from the view controller when needed. Things start to get more tricky when you're not releasing the whole hierarchy but instead simply remove some of them from the hierarchy.
In that case, I came to the conclusion that you may have buffers or layers still cached in lower API parts, and in that case your Allocation instrument won't help you.
In order to monitor correctly you'll need to use the "Memory Monitor" (in System). You'll see that the "Physical Memory Free" line dropping close to 0 is the most reliable indicator that a Memory Warning will be issued.
Another advantage of using this instrument, is that you can attach it to a running process, thus making it possible to have console output and instrument running together easily.
Circular references also won't be counted in Leaks but you can track those in Allocations. Best bet is to fire up Allocations and get to a state where you think everything should be gone (or certain objects should be). If they're hanging around go dive in to them and look at where they've been retained and sort out the proper memory ownership/releasing.
As for Allocations, there are some things that it doesn't track that can affect the overall memory. Some of the things include some CGImage backing stores, some CoreAnimation stuff and some database stuff.
Have you used the "Leaks" Performance Tool? And check out the logs in Organizer to see if there's anything there.
Also look into the dealloc for the view controllers and make sure you are properly releasing all of it's objects?

Understanding the Instrument for memory leak checking - iPhone

Above given images is of my application leaks.
Here I want to understand that, in Extended Detail - you can see different colors like light green, light pink, light brown, light purple.
What does each color indicates?
Now the other confusion is "How to locate the code which is creating a memory leak?"
Upto what limit of memory leak - the actual iPhone can go on with.
(suppose 10 bytes no problem, 20 bytes no problem & 200 bytes a problem)
What does each color indicates?
Which color indicates our code / From which detail we can get to the code where we have allocated the object & forgot to dealloc it?
(For example - On clicking of UIKit second cell in detail - we cant get to the code)
Why we must resolve all the leaks? - even a single leak can chock up iPhone ?
Why iPhone allows leaks to be remain in memory? / why garbage collection isn't done automatically after termination of application?
If I try to dealloc objects which should be deallocated according to instruments, My application terminates abnormally. If I don't dealloc, My application runs perfectly, How?
Why it is suggested that you wait in a view up to 10 or more seconds, if there is a leak, leak will be detected by Instruments?
Ignore the colors, in that one the [DashBoard viewDidLoad] is the source of the leak, something in how it's initializing a URLConnection (possibly you did not free that when the connection was finished?)
Now to answer the other questions you had:
Why we must resolve all the leaks? -
even a single leak can chock up
iPhone ?
Yes. Part of the reason is not only that you will simply run out of memory, but since there is only so much memory to go around for the whole phone a watchdog application is constantly monitoring your app and will shut it down early if it sees memory use only ever growing...
Why iPhone allows leaks to be remain
in memory? / why garbage collection
isn't done automatically after
termination of application?
All your application memory is freed when the app quits.
If I try to dealloc objects which
should be deallocated according to
instruments, My application
terminates abnormally. If I don't
dealloc, My application runs
perfectly, How?
Here I can't help, you really need to read more on the retain/release memory cycle... if you release an object that has a retain count of 0, the app crashes because the object is gone.
Why it is suggested that you wait in
a view up to 10 or more seconds, if
there is a leak, leak will be
detected by Instruments?
Because instruments works by sampling memory every so often, so it might take a little bit for instruments to get around to reading the memory after an action.
First of all, the things in the stack are colored by which library they come from, so it doesn't contain that much information.
Second, instead of worrying about how much leakage the iPhone can take, I'd focus on not having it leak.
To find leaks, there are a couple options:
Use the CLANG static analyzer when building your project
Look for leaks manually. You must always follow The Rules of memory management: if you alloc, retain, or copy an object (including using #property (retain) or (copy)), you must release or autorelease it.
The colors represent the different libraries the call stack is going through.
The leak is caused by the frame in your code that made the allocation, even if the actual allocation is taking place deep within an OS library. Instruments is showing you exactly where the leaked memory was allocated. You'll have to figure out which line in your code resulted in the leaked allocation, which will be one of the frames in the stack on the right.
The actual iPhone doesn't have much RAM available to your application. I tend to conservatively estimate about 25MB of RAM for my application to work with. Any leak, no matter how small, can sink the proverbial ship if the code is used enough.
Look for your application name in the stack extended view. Memory allocation usually shown in the end, so you know exactly which library is responsible for memory allocation. So you should trace from the line your code appear downwards till the end. Colors just make easier to trace lines of code, that are related to same libraries. Same library calls will be colored with the same color.
As for tracing leak itself. First go to your application call by double-click on the line in extended view and try to understand what exactly leaks. Sometimes you can replace the leaking call with non-leaking substitute. For example, I used a call imageNamed to retrieve images from the bundle, the application was constantly crashing because of memory shortage. I just googled imageNamed leaks and found very useful article on how to implement image cash in my application. Indeed, imageNamed API leaks. There are API that leaks in iphone SDK.
Also, try to check how you're working with alloc/retain/release and so on, whether you release or autorelease your allocated memory.
Good luck in your detective work.
I too have problems with leaks in instruments. I run my app today for the first time using leaks and found several leaks. Leaks that shouldn't be leaks because there is no way for them to leak, unless some magical code is executing and raising the retain count of my objects. I understand the memory management guidelines, know how to use autorelease pools, etc. But even an empty view based app contained leaks if i put a few controls on it. And just click around 2-3 times. Go ahead and try it. I don't really understant the information instruments is trying to provide. Are those "leaks" really leaks, or just things that are suspicious to the instruments app? Should an empty app with no user code, only a few controls put on an empty view leak memory?

No leaks appearing in Instruments, even though I'm sure they exist

I'm checking for leaks in Instruments, and I've set to check every second, but no leaks are appearing.
I'm sure there must be some in my app, is there anything which could stop these from appearing? Is there a good way I can create a leak so that I can test if leaks do show up in Instruments?
Thanks!
Creating a leak is easy:
id someObject = [[NSObject alloc] init];
someObject = nil;
Drop some code like that into your app, and you should definitely see a leak show up in Instruments.
You're only going to find leaks with a tool if an object is allocated but no longer referenced. Another type of "leak" is to hold a reference to something that you didn't intend to. This typically happens with a collection like a hash table or a dictionary where key/value pairs get left in the collection that the programmer has forgotten about.
I'm pretty sure as clemahieu postulated, what you are really seeing are over-retained objects - you think you have freed them but they still are being retained.
One quick sanity check for this is to set breakpoints in dealloc and see if the classes you expect to be freed really are.
You can also use the memory tracking Instrument (not leaks) to see what memory is still around - just make sure to select the "created and still living" option to check out just what what objects are still around.