I am getting a memory leak in my objective-C code that I don't understand. I have this code in a method that gets called several times:
AnalyzeBpm *analyzer = [[AnalyzeBpm alloc] init];
while( sample != NULL)
{
//do something with analyzer
}
[analyzer release];
When I run this code through Instruments, I get a leak everytime I allocate Analyze Bpm(which is a couple of hundred times). I looked at my AnalyzeBpm class, and everything I allocate in that class gets freed or deallocated. So why is this code creating a memory leak?
When Instruments identifies a leak, it is showing you the line of code that is allocating the leak, not the line of code that causes the leak.
Somewhere something is retaining analyzer without releasing it. You need to find that unbalanced retain. It may or may not be in the AnalyzeBpm class.
Your alloc-init and release are balanced, so it has to be something else — something in your while loop.
Related
I am getting a bit confused. I am creating an app with storyboard, and running it on iPad 1. the application uses a lot of memory, so reached the 120mb, crashes. accordingly to what I have understood to remove this problem you need to release, dealloc... the point is that with ARC this should be automatic. In fact if I add for e.g.: [label1 release]; it gives me an error. But this ARC automatic release and dealloc does not seem to work! Is this because there are different ways to release with ARC??
You don't need to manually retain/release/autorelease with ARC. However if you have active references to a lot of unused objects they will still remain in memory. Profile your app with Instruments and it will show you how many objects you're creating of each class and how much memory they're consuming.
With ARC you still need to think about memory usage you just don't need to worry as much about memory leaks.
NSObject *bigMemObj = [[BigMemClass alloc] init];
//This creates the object in memory. In both arc and manual counting the retain count is 1
//Do stuff
//Prior to ARC you would have had to call [bigMemObj release]; before setting the variable to nil
bigMemObj = nil
//With ARC you don't have to do anything. The compiler inserts the release at compile time
Also read the documentation on declaring iVars __strong vs __weak.
Without looking at your code it's hard to identify what is consuming all the memory but hopefully that should help you determine where to start looking.
You should implement #autoreleasePool{} inside each method. In essence, each method will look like the following:
-(void)methodName{
#autoreleasePool{
//do method stuff
}
}
This will ensure that, upon exiting the autoreleasePool, memory is properly released.
I can't vote this back up, otherwise I would. I think Alessandro is asking about ARC vs using release and dealloc, not about what he's loading!
So, Alessandro, your understanding is correct that with ARC you don't release or dealloc. Therefore, those won't work if you're using ARC. Also, there is no alternative to release/dealloc, since ARC doesn't use it.
My suggestion would be to look at what you're using in the app that is taking up all this memory. Do you have a large number of pictures, for example, that are very large? Keep any graphics as small as possible, matching the resolution of the iPad. Especially the iPad 1, which doesn't have the "retina display".
You can use Autorelease pools in ARC. Here is some documentation on when to use them:
NSAutoreleasePool Class Reference
Advanced Memory Management Programming Guide: About Memory Management
I have prepared a class for storing data retrieved from db, and let's say I have 10 vars in it. What if I will reuse this class for different views and each view will use a different quantity of variables.
tableViewCell will pop-up 3 vars.
View1 will pop-up 6 vars.
View2 will pop-up 10 vars.
Will the unused data cause memory leaks?
A memory leak only happens when you delete all pointers to the memory before freeing it. If you reuse your data structure, you might have some unused memory, but it won't be a leak unless you never free it when the pointers go away (leaving you no way to free it ever again).
Unused variables have nothing to do with memory leaks. You want to see a memory leak?
- (void)leakABunchOfMemory {
for (int i = 0; i < 1000000000; i++) {
NSMutableString *usedButNotUsedCorrectly = [[NSMutableString alloc] initWithFormat:#"%d", i];
}
}
That's a memory leak. An object is created with every [NSMutableString alloc], and none can never be destroyed because you lose your reference to them as soon as that iteration of the loop ends. They just go on existing and taking up space, like text-based zombies that hunger for the RAM of the living. To avoid leaks in Objective-C code, follow the memory management rules, and the equivalent rules for any other libraries you use.
running my app through Instruments "Leaks" it's saying I've got a leak which seems to happen with this code -
-(void)podAppears {
podCount ++;
NSString *podName = [NSString stringWithFormat:#"Pod%i",podCount];
Pod *thePod = [[Pod alloc] initWithOwner:self withName:podName];
[pods setObject:thePod forKey:podName];
[thePod release];
}
I can't see anything wrong, but I'm fairly new to Objective-C & memory management in general. Any help much appreciated!
That code looks fine. When Instruments informs you of a leak, it tells you where the leaked object originated. It's likely that the actual leaking of that object is occurring elsewhere in your app. You should look at other locations where you access your Pod objects.
I am calling a function repeatedly with a loop, and the loop runs inside of a thread. The thread has an autorelease pool.
I have the following code inside that function:
NSXMLDocument* undoXML;
NSData* undoData = [NSData dataWithContentsOfFile:undoFilePath];
undoXML = [[NSXMLDocument alloc] initWithData:undoData options:NSXMLDocumentTidyXML error:&err];
NSData* undoData2;
undoData2 = [undoXML XMLData];
[undoData2 release];
[undoXML release];
I'm getting the following strange results:
My program is leaking memory every time this function is called by the loop.
When I add the following code to the function:
NSData* undoData3;
undoData3 = [undoXML XMLData];
[undoData3 release];
My program leaks even more memory than before.
I'm really confused and I badly need help figuring out what's going on. Maybe my autorelease pool isn't working correctly? Why is this happening?
Are you sure it is leaking? Or is it simply growing in size?
What does your loop look like and how is the autorelease pool integrated into it?
The autorelease pool must be inside the loop or your loop will just build up tons of memory over time. That the leaks instrument doesn't show leaks indicates that you have violated the memory management rules or your loop is incorrect.
Try running Instruments on your project w/ the leak detection settings. This should identify exactly where your leak is occurring (even in the system libraries).
Run -> Run With Performance Tool -> Leaks
undoData should be preset to be autoreleased (according to naming convention dataWithContentsOfFile: returns an autoreleased object). But unless you have your own autorelease pool, nothing that is set to autorelease will actually be deallocated until the active pool is drained (i.e. sometime after your function returns).
Your thread may have its own autorelease pool, but unless you are creating one inside your own function, nothing will be deallocated until after your function exits.
If you want to trigger the draining of autoreleased objects in the middle of a function (say once per loop), you need to manage your own autorelease pool.
while(looping) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// do stuff that produces autoreleased objects
[pool drain];
}
Also, per cobbal's comment on your question, it looks like you should not be releasing undoData2 (or undoData3). Based on the naming convention -[NSXMLDocument XMLData] should be returning an autoreleased object.
If you have access to the source code of the NSData class you should look at what objects are being instantiated when undoData3 is created. I say this because you create the object and immediately destroy it. The issue must be that memory is being allocated inside the class but not being deallocated in it's destructor.
If I alloc and init an object in a method that is called quite frequently, and if I don't release it immediately, does the object become a memory nightmare? Or will the alloc and init be ignored if the object is already in memory?
This is somewhat difficult for me to explain, sorry!
Thanks.
Without garbage collection, if the object in question is never autoreleased, it vanishes the instance you release it. Even if the object is autoreleased, you can make your own autorelease pool and wrap your loop with it.
In garbage collection, then it's a little bit harder to predict, but the garbage collector should do a decent job of handling objects that are all allocated near to each other.
Without knowing what you're doing exactly, it's hard to say, but it sounds like you're doing:
for (...)
[[Foo alloc] init];
In which case you'll leak, just as if you did
for (...)
malloc(...)
or
for (...)
new ...;
If you're in a GC environment this isn't a problem (in Obj-C 2, with GC enabled retain/release don't have any effect at all). If you're not using GC then you're leaking every object that you alloc.
Alternatively, if you're doing something like
for (...)
[[[Foo alloc] init] autorelease]
You won't leak indefinitely, but none of your instantiated objects will be collected until you return to the top of the event loop (ie. your event handler finishes). In this case you can end up using lots of memory at once, without actually leaking it in the long term.
Have you profiled your code? If so, you know if this is a hot spot. If not, your working in the dark.
You mentioned in a comment "I'm calling this method every time a timer fires, which is a few times per second", in which case its completely irrelevent, the cost of allocating memory for an object a few times a second will be completely negligible.