How free memory immediately in iOS? - objective-c

When you do a release, you do not immediately remove the memory. I used this code and I can see the memory before and after the use of release and it do not change. Ok, it will be release after some time.
But, what can I do for release all memory I can before start a library that will use a lot of memory? Or how can I immediately release memory?

Memory Management is a big thing in iOS but this tidbit of information helped me a lot during my development.
"Each object has a "retain count" which is increased by calling "retain" and decreased by calling "release". Once the retain count hits 0, the object is released and the memory can be used for something else.
You can "autorelease" objects. This means the retain count isn't immediately decreased, but is decreased the next time the current autorelease pool is drained.
iOS apps have an event loop in which your code runs. After each iteration of the event loop, the autorelease pool is drained. Any object with a retain count of 0 is released.
By default, autoreleased objects are returned by methods that don't begin with new, copy, mutableCopy, retain or init. This means you can use them immediately but if you don't retain them the object will be gone on the next iteration of the run loop.
If you fail to release retained objects but no longer reference them then you will have a memory leak, this can be detected by the leaks tool in Instruments.
One strategy is to autorelease everything returned by the above named methods and store objects in retain properties (or copy for strings). In your object's dealloc method, set all your properties to nil. Setting a retain/copy property to nil releases the object that it currently points to. As long as you don't have any circular references (avoided by not using retain properties for "parent" objects such as delegates), you will never encounter any leaks."
here is the link to the thread for this information
http://www.quora.com/What-is-the-best-way-to-understand-memory-management-in-iOS-development
It's a good thread with some useful code examples as well as other references.

Release frees the memory immediatly (assuming it's the last release). That means, it can be used by your application again when allocating.
Note that every applications have some chunks (pages) of free memory assigned by system and when allocating/deallocating part of a page, the released memory is not returned automatically to the system. It's just marked as free and can be used again by the application.
To understand all this, you need to learn something about how operating systems handle memory allocation, virtual memory etc.

Related

Understanding Instruments and Memory Management

I'm in need of understanding how memory is managed in objective C.
I know the basics, if you create it and own it, you must release it yourself.
However, when it gets to code such as:
self.storeDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath2];
Do I own this? Must I release this memory?
self.storeDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath2];
//73.3% leak
totalCharacters = [storeDict count];
tagCounter = 1;
dictKeyArray = [[storeDict allKeys] mutableCopy];
//13.3% leak
When Instruments puts a bunch of percentages next to the highlighted leaks, what does that tell me? Does it tell me the size of the leak relative to the total amount of memory leaked?
And one last thing.. Is it normal for the amount of allocated memory to continuously rise? Or should it stabilize somewhere?
Thanks for all the help! Everything is greatly appreciated!
In most cases, you only own objects returned by methods whose names begin with "alloc", "new", "copy", or "mutableCopy". Of course, you also own anything to which you send -retain. Exceptions to these rules should be called out in the documentation for the non-conforming methods.
See https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-SW1
Instruments attributes a leak to the line where the object was created. However, that's not necessarily the code which leaked the object. If the pointer to the object was passed to some other code and that code did not balance its retains and releases, then that code is responsible for the leak. Instruments can show you the history of retains and releases for a specific object, and you'll have to review those to see which code is not discharging its ownership responsibilities properly.
Also, if an object is owned by another object and it's really that second object that was leaked, then everything it owned will have leaked "transitively" as it were. So, look for higher-level objects which have leaked before trying to track down low-level objects which have leaked. Often, it is the objects which have leaked fewer instances which are the root of a graph of leaked objects.
Whether it is normal for memory to keep rising or to stabilize, that depends a little. Usually, memory usage should stabilize. However, if your app really is doing more and more, then it may be normal for its memory usage to keep increasing. For example, if an app is receiving data over the network and accumulating results as it does so, then its memory usage would likely rise as more data arrives. But if it doesn't stop at some reasonable point, that's a problem. On an iOS device, the system will eventually kill it.

What exactly use of dealloc method in Objective c? when it will call?

My Question is When the dealloc method will cal before the application termination, If it happens , When the application terminates all the memory of the objects and application will be removed from memory, then what is the use of writing dealloc method?
This is a general question about memory management. You use dealloc in Objective-C, free in C etc. to clean the memory allocated for the variables that are no longer in use. When the application terminates of course all of the memory allocated by the application will be released. However, if your application keeps allocating memory as it runs, and if the user runs the application for long enough, unless you release unused memory, the device's memory would get eventually used up. This is why you need to use dealloc.
The dealloc method describes how the object will be released. When an object is being deallocated unless you override the dealloc method only the object's pointer will be released. Therefore, in order to release properties and fields in your object you need to manually release them in your dealloc method.

Objective C - Memory Management and autorelease ???

Does autorelease guaranty that at the end of blocks the object will get released?
Or is it better to manually release objects?
It guarantees it will be released sometime after the block executes, not necessarily immediately after. It's up to the runtime to determine exactly when.
It's not big deal unless you're doing something with a lot of autoreleased variables, like creating them in a big loop, or if you're creating large autoreleased objects, like UIImages. In these cases, you should manually release when you're through, otherwise autorelease is perfectly acceptable.
If an object is autoreleased, you MUST not manually release it (unless it is retained of course). The NSAutoRelease pool which is part of the UIKit event handler will release it for you. If you were to manually release the object, the pool may cause a crash or other undefined behavior as the object will be doubly-released.
If there are cases where you generate a lot of objects or use a lot of memory in objects, you can pre-emptively autorelease them (perhaps in your loop) by creating your own NSAutoReleasePool - pools can be nested.
It's better to release objects rather than autorelease, unless of course you have an explicit reason to use autorelease, for example use autorelease when returning an object the method retained and you can't avoid it.
Basically autorelease should be used as an excuse to completely avoid memory management. You want to release objects as soon as you possible can. Autorelease just says the object will be released some time in the future.

NSString or NSArray release?

When I perform a [NSString release] or [NSArray release] or [NSMutableArray release], what happens?
Does the memory became wiped out?
Or just pushed on the stack and dropped from the heap, or vise versa?
If I just want to dump memory when I am done with it, is "release" the best thing to use?
I am dealing with many matrices and don't want them sticking around using memory...
thanks
Just read the Memory Management Programming Guide and your questions will be answered.
Also, if you're dealing with a lot of matrices you may want to use manual autorelease pools.
When I perform a [NSString release] or [NSArray release] or
[NSMutableArray release], what happens?
The retainCount of the instance that you call release on is decremented. If it reaches 0 as a result of your call, then the instance will be deallocated.
Does the memory became wiped out? Or just pushed on the stack and dropped from the heap, or vise versa?
Not necessarily. The memory may become wiped out (in the sense that it no longer contains a valid object instance and may be overwritten by other things) once the retainCount reaches 0 (or less if you over-release something), but this is not guaranteed to happen immediately upon your call to release. The released instance may in fact stick around for quite awhile, if it is associated with an NSAutoreleasePool that is not drained frequently or if someone else has called retain on it.
If I just want to dump memory when I am done with it, is "release" the
best thing to use?
In general, yes. If you want really low-level control of things, you can also use malloc() and free() instead, which will release memory more immediately than calling release will.
When you perform a release, the use count in the object is decremented. If the use count decrements to zero (because it's not simultaneously "owned" by some other code or data structure), the heap space occupied by the object is marked as available for reuse.
When a new object is allocated, the heap is searched for an appropriately sized piece of reusable space, and if your recently freed piece is the first one found to match the required size, that storage is marked "in use" again and your old data is overwritten with the new object.
Note that this means that if you release an object too soon you may still be able to use it for awhile, but it can suddenly, at any time, go "poof" and turn into an entirely different object, causing mysterious errors.

How should I memory manage objects returned by instance methods?

Plenty of Objective-C classes return objects. Statements like [[instanceOfNSWhatever objectForKey:aKey] stringValue], for instance, appear all over my (and hopefully everyone else's code).
How am I supposed to memory manage these "intermediate" objects?
Were they just created or did they always exist?
Can I retain them, and if I release the object that created them, will they be released as well?
Are they autoreleased?
What if I run [instanceOfNSWhatever stringValue] a million times in a loop? Can I dispose of all those NSStrings as needed?
I'm still learning ObjC, and while I've been good at balancing my retain counts overall, I'm definitely lacking some understanding about how these methods work. Can anyone fill me in?
You've probably already read this section of Apple's docs about memory management, but I'll point you to the section about the Object Ownership Policy just in case. You are only responsible for managing the memory of objects you "own". To quote the docs:
You own any object you create.
You "create" an object using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy).
If you own an object, you are responsible for relinquishing ownership when you have finished with it. [ie: release]
If you do not own an object, you must not release it.
The "Simple Examples" section of those docs provide good elaboration, but to put the points above in the context of your specific questions:
How am I supposed to memory manage these "intermediate" objects?
The good news is: you don't. Ignore the the memory management aspect of the "intermediate" objects in your example.
Were they just created or did they always exist?
They may have always existed, or they may have just been created. The beauty of objective-c is that you, as a consumer of those objects, don't have to care.
Can I retain them, and if I release the object that created them, will they be released as well?
You don't need to retain them if you're just passing them on to some other function, or using them as intermediate values yourself in your own calculations within the function. Say, for example, that you're returning the stringValue from your example function to someone else. There's no point in retaining it just to return it.
If you DO happen to retain it, then yes, you are responsible for issuing a corresponding release message as some point. You might, for example, retain the stringValue from your example if you want to hold on to that value as a property in your own instance. Objective-C uses reference counting. If you need that object to stick around for a long time, you must retain it so that someone else's release message doesn't cause it to vanish if the retain count falls to 0.
Are they autoreleased?
Depends. Let's say you ask for a string from instanceOfNSWhatever. If instanceOfNSWhatever has to create that string just special for you (in order to service your request), but doesn't otherwise care about that string, then yes... instanceOfNSWhatever probably put that string into the autorelease pool. If the string was already a property of instanceOfNSWhatever and it was just sending it to you in response to your request, then no, it probably wasn't autoreleased.
Again, the beauty is: you don't know and don't need to care. Since instanceOfNSWhatever created the string, it is responsible for managing it. You can ignore the memory management unless you add to the string by sending it a retain message.
What if I run [instanceOfNSWhatever stringValue] a million times in a loop? Can I dispose of all those NSStrings as needed?
No need. Again... stringValue isn't yours to manage because you didn't create it. As a technical note, if instanceOfNSWhatever really did have to create 1 million copies of stringValue to service your 1 million calls, it probably put them all in an autorelease pool, which would be drained at the end of the current cocoa event loop. Fortunately, unless you send each of those stringValue objects a retain message, you can gleefully ignore the memory management question here.
You basically manage all your memory according to the Memory Management Programming Guide for Cocoa. In short, however, you basically only need to worry about objects that you "own". You own an object if you create it (in Cocoa, you create an object by specifically allocating it using alloc or copying it using copy or one of their derivatives). If you own an object, you are responsible for releasing it when you are finished with it.
Any other object is, therefore, not owned by you. If you need to use such an object for any extended period (for example, outside the scope in which you received it), you need to specifically take ownership of the object by either sending it a retain message or copying it.
To answer your last question, if you are creating a lot of temporary objects in a loop or some other way, you can create your own autorelease pools. See the documentation for NSAutoreleasePool for more information about using them. Please note, however, that you should really only do this after you've profiled your application and found that it is using too much memory and would benefit from this kind of optimization.
Finally, if you are creating and releasing a lot of heavy objects and don't want to rely on autorelease pools, you can specifically allocate and initialize them and then make sure to release them on your own as soon as you're finished with them. Most objects that have convenience creators have similar initializers for creating the object specifically.
When working on the iPhone/iPod Touch, the autorelease objects are released when your application exits. This may be what you don't want. Especially when working with images or large chunks of data. To insure large pools of memory that are tagged autorelease get released sooner, create local autorelease pools. Like this:
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
-- do something that creates large autorelease memory blocks --
[localPool drain];
If you don't do this, you will find your application exiting unexpectedly.
I'll tell you a simple rules I wish I'd known when I first started Objective-C :)
If an method contains the words "alloc" or "copy" then you must [release] the object when finished.
If a method does not contain these words, you must [retain] it for it to remain valid outside of your function.
If you call [retain] you must later call [release] when finished.
This covers practically all you need to know about the basics of memory management.
ObjC makes heavy use of what are known as "auto release" pools. Objects returned from non alloc/copy functions are placed into these pools and automatically freed after your function exists.
That is why you do not need to release the results of something like [obj stringValue].