How to solve memory allocation in ios ?give me the right way to solve memory issues and memory leaks.
The best way to avoid these Memory issues is through proper coding. Just go through the Apple reference on Memory Management.
You only release or autorelease
objects you own.
You take ownership of an object if you
create it using a method whose name
begins with “alloc”, “new”, “copy”, or
“mutableCopy” (for example, alloc,
newObject, or mutableCopy), or if you
send it a retain message.
You use release or autorelease to
relinquish ownership of an object.
autorelease just means “send a release
message in the future” (specifically:
when the used autorelease pool
receives a drain message—to understand
when this will be, see “Autorelease
Pools”).
Without more info all I can say is...
Release anything you init and/or alloc that is not autoreleased.
Delete anything that you call "new" on
free any data you malloc
Use Instruments to diagnose where your leaks are occuring.
Release anything you retain
release anything you init that is not autoreleased.
#Nipin, For solving memory issues, you'll have to release each object that you're allocating... ie, use [yourObject release]; for each object you call alloc method... Also, unload any textures that you're using [texturename unload];
[texturename release];
Do all these when you no longer requires those objects or textures and in most cases it can be where you exit from the scene...
follow the below link memory management
another link is small guide for quick point small article
Related
I'm developing an iPhone application, and I very new on iPhone development.
I've created some custom classes with instance variables (NSArray, NSString, etc.). All classes inherits from NSObject.
Should I create a dealloc method to release all instance variables?
Thank you.
Yes, you definitely need a dealloc if you are keeping instance variables that are objects. You will also probably need to retain or copy those as well, depending on how your object creates/uses them.
Check out this article on memory management. I think it explains it pretty well. You must also read the Memory Management Programming Guide for Cocoa. Even if you don't fully understand everything, read the whole thing through, then read the article, then do some work, get some crashes and read it again :) eventually it should all click.
In iPhone development its pretty much SOP to have a dealloc since there is no garbage collection.
You have to release any object your class has ownership for. That means, yes you have to overwrite the dealloc method and release the objects there.
Normally you have ownership over values (objects) in instance variables, but it also depends own how you create them.
You should definitely read the Memory Management Programming Guide, it describes pretty well when you gain ownership.
Yes, having a dealloc method is normally the best way.
If you want to reclaim memory used by your instance variables you will have to release them when you are done with them. You could add a method to do this clean up:-
- (void)cleanUp {
[myArray release];
[myString release];
}
Call it when you no longer need the instances.
Now, the chances are that the point in time when you want to release these variables is the point in time when their parent object is destroyed (parent object is gone, so instance variables are no longer needed). As -dealloc is automatically called for you when the parent object is going to be destroyed - it makes more sense to put the cleanup code in dealloc than in our -cleanup method that we have to call at the right time.
If you don't want to reuse the memory, eg. if you are never going to be finished with the instance variables, then you don't need to release them and might not need a -dealloc.
I am trying to follow the Apple's recommendation to handle low-memory warnings (found in Session 416 of WWDC 2009 videos) by freeing up resources used by freeing up my dataController object (referenced in my app delegate) that contains a large number of strings for read from a plist:
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
[_dataController release];
_dataController = nil;
NSLog([NSString stringWithFormat:#"applicationDidReceiveMemoryWarning bottom... retain count:%i", [_dataController retainCount]]);
}
But when I run ObjectAlloc within Instruments and simulate a Low-Memory Condition, I don't see a decrease in the memory used by my app even though I see the NSLog statements written out and the retain count is zero for the object. I do pass references to the app delegate around to some of the view controllers. But the code above releases the reference to the _dataController object (containing the plist data) so I would expect the memory to be freed.
Any help would be appreciated.
Are you sure that app delegate is the only owner of _dataController? -release only decreases the ref count, it won't deallocate the object unless the ref count drops to zero.
If _dataController is owned by other objects too, send a message to them to release it.
I am double-checking that. Thanks for the input! I did reread the memory management docs from Apple and I did put an NSLog statement in the dealloc method of my DataController and it is being called. I also put wrote out the retain count before the release and setting to nil of _dataController. The retain count is 1.
So this drives me back to why I am not seeing a significant decrease in memory usage. I think I need to understand the ObjectAlloc display in Instruments better and where the largest allocations of memory are taking place in my app. After searching for help in this area, I am frustrated with trying to determine from Instruments where this occurs. I can see that there is 3.54 MB for "All Allocations" and 608 MB for Malloc 32.00 KB. If I drill down on Malloc, I only see the Responsible Caller as being framework calls like png_malloc and inflateEnd. I am looking for calls within my code that is responsible for the Malloc but I don't see that. All this to say that I wonder if I am releasing the object or objects that will really make a significant difference in the amount of memory used for the low-memory condition. I think I need an in-depth tutorial for Instruments. The Apple help docs are okay but an example with code would be more helpful.
I found that the iphone have viewDidUnload, and dealloc. I want to release the object. Which method should I use to release the object? What's the different between them?
Send release or autorelease to release an object. You shouldn't send dealloc; the Obj-C runtime will do that.
If you're asking where you should release an owned object, read: "When should I release objects in -(void)viewDidUnload rather than in -dealloc?"
Do not call dealloc. Use the retain-release model for memory management, and Objective-C will take care of deallocating memory for you.
See this link for a good explanation of how retain-release works.
The difference is that viewDidUnload is used to release "spare" objects in low memory situations while dealloc is used to release all objects when the view is no longer needed.
This means that you will almost always have a dealloc method but have a viewDidUnload method only where it makes sense.
I have been tracking down why NSObject references, while being explicitly release, still show up in ObjectAlloc. In fact, have reduced down NSObject to a basic shell, with a [[myObject alloc]init] immediately followed by a [myObject release], and it does not look like it is being released in ObjectAlloc. This is a big problem with a NavigationController app that pushes/pops multiple view controllers, as the recently popped viewcontrollers aren't being released, because of these 'unreleased' NSObject references. Hmmmmmm.
I could put my code up here, and have a bunch of 'have you's that never get anywhere. Autorelease pools, blah blah.
So, let's look at the Sample 'SeismicXML' sample app from Apple... fire it up in ObjectAlloc/Leaks. Very basic in getEarthquakeData:
XMLReader *streamingParser = [[XMLReader alloc] init];
[streamingParser parseXMLFileAtURL:[NSURL URLWithString:feedURLString] parseError:&parseError];
[streamingParser release];
I see a TON of junk laying around in ObjectAlloc from XMLReader, despite releasing it. I bet if we put a 'refresh' button on this app to call 'getEarthquakeData' again, we would crash the app within 5 refreshes.
Any thoughts?
I think you are confused about the ObjectAlloc instrument which will show all object allocations for the lifetime of your application. It's main use is to track memory usage over time.
The instrument I think you want is the one that is called Leaks which shows you what memory is being leaked by not having any reference to it. That is pointers to objects not being sent release-dealloc before they are reassigned.
There might be an autorelease pool holding onto the object. If you create many autoreleased objects without cleaning them out of the pool, you'll get leaks until you return to the outer loop with the autorelease pool.
Here's how autorelease pools work: in the main loop, there's an autorelease pool. Everything autoreleased goes there. At the end of every loop iteration, all the objects in the pool get released. If you allocate objects in another loop somewhere, they won't actually get released until you return to the main loop. Unless, of course, you create your own autorelease pool just for the loop.
Another problem could be that your object is never released. If you get an exception between +alloc and -release you'll get a leak. A way to fix this is to use instead:
[[[XMLReader alloc] init] autorelease]
Finally, you could be working with garbage collection here. I don't know enough about the GC system to tell you what behavior you should expect.
I am wondering what the difference is between release and dealloc? After reading, the memory management rules (See below)., I am thinking most of the time I will be using release. However, I wanted to know what to do for properties.
#property(retain)....
I have been using dealloc but after reading this article I am not sure that is correct.
You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.
You should never call dealloc on anything other than super.
The only time you will be calling dealloc is in the dealloc method of a custom inherited object, and it will be [super dealloc].
When the retain count of an object goes down to zero, dealloc will automatically be called for you, so in order to manage memory properly, you need to call retain and release when appropriate.
If this isn't clear to you or you'd like details about how memory is managed in Cocoa, you should read the Memory Management Programing Guide.
You never call dealloc directly. It is invoked by the system when the retainCount of the object goes to 0. Every time you do a retain, the retainCount is incremented with 1. Every time you do a release, it gets decremented. This way, by balancing your retains and releases, you ensure than when the retainCount gets to 0, dealloc will be automatically called, and your object freed.
As Ben S noted, the only time and place you would call dealloc is in in the dealloc method of an inherited object.
When you use #property(retain) and then #synthesize to generate the property code, you do not need to do any manual memory management on the property. The other answers are correct in that you shouldn't be using dealloc except in your own override of a parent class dealloc.