Using Instruments for Memory Leak Checking in XCode? - iphone

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".

Related

Strange memory leak when calling SBJSON

I've been thoroughly testing my app using the Leaks tool in Instruments, and occasionally a leak comes up when using SBJSON. Having looked over the net it appears that SBJSON tends not to leak by itself, so it must be the way I am calling it. Here's a screenshot of the offending line in my code, pointed to by the Leaks instrument:
This leak is detected about 15 minutes into execution in this particular run, and is completely unpredictable in when it may happen. Instruments says the leaked memory is of type NSNumber, and this highlighted line is contained in a method that is called all the time throughout the execution of the app. I've tried outputting the value of the _source string to the console but there's nothing strange about the output when the leak occurs. Here's another screenshot showing the history of the leaked block:
I am running the app on the iPhone 4.2 simulator, and my testing basically involves clicking around every view in the application to make sure it all runs okay. As you may be able to see in the screenshot above, the JSONValue call goes to the method defined in NSString+SBJSON.m so I'm pretty sure if there is a problem it's in my code. Any idea what I am doing wrong?
When you assign _object = [[_source JSONValue] retain]; you increase reference count of object returned by JSONValue. In method initWithData:(NSData *)data this object is not released. So Analyzer thinks that there is memory leak.
You should check if you are releasing _object before losing reference to it or in dealloc method:
[_object release];

NSAutoReleasePool appears not be working

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...

Memory Leak on device when using mutableCopy

I thought that I was really close to release this new App of mine when I ran into a dead end. My code works without memory leaks in the simulator (Xcode 4.0.2) but reports memory leaks on my devices.
I think my issue is related to that I copy an object, because in my troubleshooting attempts I tried without a copy, and then the memory leak goes away (but of course so do my functionality!).
What I do is that I add a number of instances of a subclass of UIView to an array . This subclass(Cities of which cityToAdd is an instance) has two UIViews and some variables that I need to access at a later stage.
If I do this I get memory leaks on my devices:
[arrayOfCities addObject:[[cityToAdd mutableCopy] autorelease]];
But if I do this I don't (but loose functionality)
[arrayOfCities addObject:cityToAdd];
In the subclass I have this to handle the copying:
- (id)mutableCopyWithZone:(NSZone *)zone{
Cities *newCity = [[Cities allocWithZone:zone] init];
[newCity initWithCityName:cityName
onRing:ring
withTimeZone:timeZone
withTimeZoneOffset:timeZoneOffset
withDSTAngle:DSTAngle
andDST:isDST];
return newCity;
}
From Instruments I get this when testing on a device:
and when I drill down on the second row it shows this:
Finally my initWithCityName method (sorry for such a long post!!) I put it as a picture to get the colors and messages from Instruments...
Finally the UIIMage imageNamedUniversal is an extension to give me #2x images on the iPad (but I have tried with the normal imageNamed and get the same memory leaks).
I dont know where to start!! Appreciate any ideas.
Thanks
Why are you calling two initialization methods? You are calling init and initWithCityName....
Two things to consider:
After you add cityView and DSTView as subviews, you can and should release them.
And you are initializing newCity twice in your copyWithZone.
Thanks for fast replies and suggestions. You got me on the right track. The cityToAdd that I added to my array was added several times in a loop, but I kept the alloc and init outside of the loop. Once I moved it inside the loop it works in both simulator and device.
Weird that the simulator don't report that memory leak though...
Again, thanks for your fast replies!

Finding memory leaks using Instruments in iPhone

i have been using Instruments in Xcode to find out the memory leaks in my app. I was really impressed by this tool but was also a bit dissapointed because, it is a bit difficult to understand the way is shows the leaks. I have posted the line of code and i request you to go through it once. The instruments tool is showing a memory leak in a line where i din't even alloc the object. i have noticed similar kind of behavior at many other
lines as well. Also, memory leaks are still being shown by instruments even after releasing a object.... Can anyone help me this please.....
NSCharacterSet *trimSet=[NSCharacterSet characterSetWithCharactersInString:#"\t,\n, "];
NSString *resultString=[currentCharecterString stringByTrimmingCharactersInSet:trimSet];
Thanks and regards.
The meaning of Instruments report is that the object allocated on that line is leaked, not that this line is causing the leak.
You're probably retaining your string somewhere below.

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.