NSObject release... Still shows up in ObjectAlloc - iphone

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.

Related

iphone memory allocations and leaks

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

Cocoa touch - Memory Management

I am a former java programmer, and I am having some troubles managing the memory on cocoa touch.
In fact, I think I got the retain/release trick, but still I am not sure I got it right.
For example, I am creating and adding a subview to the main window:
aViewController=[[AViewController alloc]init];//aViewController is (nonatimic,assign), so retaincount = 1 after this line?
[self.window addsubview aViewController];
[aViewController release];//retaincount=0?
And in aViewController I have an IBAction:
[self.view removeFromSuperView];
How can I be sure the object aViewController gets completely 'deleted' and memory released after I removed it from superview (think that controller as a graphic-heavy view controller)?
Also, generally, is there a way to be sure an object is deallocated? I am aware that if I ask ownership of an object I have to release it at a certain point, but what if I just want the object's pointer to be null at a certain point(not basing on the retaincount)? Should I call dealloc directly? I find sometimes very confusing to keep under control the retain/release mechanism.
If someone could give me a quick breakdown to make my mind 'click', i would be extremely grateful.
Thanks.
The short answer is you shouldn't worry about when an object gets deallocated (unless you are debugging a memory management problem). You should just worry about ensuring that if your code retains, copies or inits an object, it releases or autoreleases it. By doing so you will ensure reference counts are properly maintained and hence deallocation will be managed for you.
Leave the task of deciding when to dealloc an object to the runtime. Never call dealloc directly unless you are calling the super classes dealloc method at the end of your objects dealloc method.
Also, don't even look at the retain count property of an object. Various pieces of the framework manipulate those too during the lifetime of the object, and you'll see that number move around seemingly at random. It'll just drive you nuts.
The really important thing is to make sure you've got the objects retained that would be a problem if they went away suddenly, and released when you're okay with them going away suddenly.
aViewController=[[AViewController alloc]init];retainCount is 1
[self.window addsubview aViewController.view];retainCount is 2 (adding the view increments the retainCount)
[aViewController release];retain count decrements to 1;
[aViewController removeFromSuperView];retain count decrements to 0;
Now the dealloc method will be called the allocated memory will be freed. This is what have understood please correct me if i am wrong i always find difficulties during memory management.

How can I tell if a referenced object has been deallocated in objective-c?

After upgrading to iPhone OS 4.0 the application started to crash after switching between applications. The application crashes in the same place when the application receives a memory warning.
It seems like some objects are automatically deallocated when a memory warning is received and then when we try to use the deallocated objects the application crashes.
Is it possible to test if an object has been deallocated, so that we can reallocate them?
You can't test whether a specific object has been deallocated because after deallocation, the object no longer exist. The only thing you can do is test whether a reference to the suspected object from another object is still non-nil.
Your problem here isn't deallocation per se but rather mismanaged retention. You have an object that has been marked as no longer being in use and the system is killing it as the system should. The only reason that you see it during low memory is that the system stops and drains all the release pool instantly instead of waiting for the normal cycle.
You need to make sure you have properly retained all the objects you need so they won't be improperly released. A retained object is not deallocated even in low-memory situations.
Edit
I would add that the most common cause of low-memory crashes is assuming that a view or a resource in a view is always present even when the view is not displayed. The system will purge undisplayed views and their resources (like images) in low-memory. Check the didReceiveMemoryWarning of the view controllers.
You can add
-(void)dealloc { ... }
And leave it empty if it's the right to do, and add breakpoint in it.
This answer correct to ARC and NON-ARC
Implement the method dealloc inside a UIViewController to see the moment it is being released from memory
- (void) dealloc
Print the reference of any object you want to test.
NSLog("Get pointer: %#", self); // ViewController
Then set a break point at a place where you want to test if the object is still existing. If you ran into the breakpoint, check the objects pointer in the debugger with
`po [pointer_printed_before]
Here you can see, the pointer is not available anymore, there is no object anymore after the dealloc method printed a log.

Need Help on didRecieveMemoryWarning in iPhone

I am developing an application which has almost 12 view controllers. Application has tabBar with 4 tabs means four view controllers and there are multiple views to navigate in each tab bar. Please note each tab has a navigationController with a rootviewController being its firstview. Application is an extensive database application. When I run on simulator it works nice but get didRecieve memory warning while running on the device. I have few questions regarding the same.
NOTE: I have checked the application using Instruments tool for Leaks and there are no red pyramids which means there are no leaks in the code.
What is the best practise when you deal with multiple view controllers.
when I recieve memory warning, I call [self deleteObjects] which deletes all the instances which are retaning the values for the current controller. But I am not confident if this the right way. What should be done when we recieve memory warnings. Is there any good tutorial for that. (Links plz)
Also how to make sure that the [self deleteObjcts] is not called for the visible controller.
(I was calling the deleteObjects method in viewDidUnload method before but since we do [super didRecieveMemoryWarning] it breaks the code as viewDidLoad is called in hierarch from top to bottom so once I deleted object for top viewController obviously there will be error for rest of the controllers.)
Some of the basic confusing questions for me are as follows:
Why the memory warnings are not consistent. Like I get them sometimes at the start whereas sometimes there are no warnings.
When we used [NSDate date], [UIImage imageNamed:#"..."], [NSString stringWithFormat] etc, we dont own these objects and we dont have to release them but how can we make sure these objects are relased when we recieve a memory warning.
I am using NSMutableArray at multiple places. In this arrays I store the [NSString StringWithFormat ], [UIImage imageNamed...] objects, so when I realease the arrays do I need to relase the objects in the arrays though I dont own them.
Though this is a big list of question but I appreciate your help and time since I am in last stage of my development I am facing these major challenges.
You receive memory warnings when you run out of memory. Memory is not only taken by your App, all other running processes use memory and the memory being used may always vary.
Those object are all autoreleased. The NSAutoreleasePool will take care of releasing the objects, you should never release such an object yourself (well, not as long as you have not retained it yourself). This doesn't really matter, autoreleased object will be released quite quickly.
When putting an object in an array, it will be retained. When you release the array, it will send release all it's children objects. As you store autoreleased objects in the array, they will take care of their own releasing. This has probably already happened when you release the array, so -dealloc will be called on all the objects immediately.
NSMutableArray *someArray = [[NSMutableArray alloc] init];
NSDate *date = [NSDate date]; // Autoreleased object. Retain-count is 1
[someArray addObject:data]; // The array retains the data object. Now has a retain-count of 2
// Some other things
// The date object has been called release at some time (because it was autoreleased)
// so date now has a retain-count of 1
[someArray release] // Will release all containing objects thus date will be called dealloc
I've run into memory problems with UIImage imageNamed that I think are caused by the OS caching images and not releasing them when it should. There are lots of other developers who have seen the same thing.
I would try using imageWithContentsOfFile instead of imageNamed and see what happens.
For example forPNG images --
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"filename here" ofType:#"png"]];
Here's a thread that covers what I'm talking about:

Memory Usage on convenience method vs init method

Recently when I looked into iPhone memory management, I tried to compare the convenience method and init method on the same object. For example, I have UIImageView where it displays a downloaded NSData:
Convenience method:
imageView.image = [UIImage imageWithData:[downloads dataAtIndex:0]];
init method:
UIImage *aImage = [[UIImage alloc] initWithData:[downloads dataAtIndex:0]];
imageView.image = aImage;
[aImage release];
When I try to go back and forth on the views to increase the memory usage and hit "Simulate Memory Warning", the memory usage for the app went from 20MB to 18MB with convenience method, and init method went from 20MB to 13MB immediately.
I also waited and interacted with the app to give time on releasing on the convenience method's autorelease. But it didn't drop much.
Other than the autorelease vs release, what else contributed the difference?
Your autoreleased objects created by the convenience methods will not be released until the containing autorelease pool is drained. It is advisable to wrap memory intensive operations inside of an NSAutoreleasePool block if you will be making heavy use of them.
The only difference that could be causing this is that imageWithData: doesn't use the system image cache, while initWithData: does. So maybe the image that's made with the initializer can release it's image data when it receives a memory warning since it can go back to the system cache, while the one that's created by the convenience method can't.
Objects created with convenience methods are autoreleased, as I am sure you are aware. However, if you have no AutoReleasePool in the RunLoop where you are creating the image, then the object will be added to a non-existent pool, and never properly cleaned up. This may be the case if you are running in a thread, and have forgotten to create an AutoReleasePool for that thread.
To verify if this is the case, you could run Instruments (Leaks) and see what it reports.
Something that I have noticed is that with autoreleased objects, under memory pressure, there is a system GC that occurs with a noticeable performance hit if you don't release your pools in a timely fashion.
Also, using the init / release method allows your memory consumption in loops to remain flat, while using a autorelease pool creates spikes. In some memory challenged contitions, the rapid increase of objects in the autorelease pool may cause your application to get booted before the system takes steps to clean up stuff like emails being open, mobile safari tabs, and iTunes stuff running.
Bottom line, I tend to use init more because it makes my application's memory consumption more consistent and I see fewer problems with getting booted randomly. The gradual increase in memory consumption lets the daemons clean up the system without killing my app. Finally, as somewhat of an aside, if you are using the #property keyword in your classes, you have to be careful with stuff like:
myProperty = [NSMutableArray arrayWithCapacity:10];
Because what will happen is when the pool in your main.m class gets collected that item will be gone, causing a crash due to calling a method on a released object. If you are setting it with #property (nonatomic, retain) you will want to use:
self.myProperty = [NSMutableArray arrayWithCapacity:10];
to make sure it hangs around. You can avoid all of that by just going with alloc init however. Just watch your reference counts to make sure you don't have double references causing memory leaks.