Monday, December 9, 2013

Garbage Collection in iOS (iPhone)

Garbage Collection
When you use the Cocoa garbage collection technology, it manages your application's memory for you.
There is no need to explicitly manage objects' retain counts to ensure
that they remain "live" or that the memory they take up is reclaimed when they are no longer used.

How the Garbage Collector Works (here collector or collection means GC)
When a collection is initiated, the collector initializes the set with all well-known root objects. The collector then recursively follows strong references from these objects to other objects, and adds these to the set. At the end of the process, all objects that are not reachable through a chain of strong references to objects in the root set are designated as "garbage." At the end of the collection sequence, the unreachable objects are finalized and immediately afterwards the memory they occupy is recovered.

The initial rootset of objectsis comprised of global variables,stack variables, and objects with external references. These objects are never considered as garbage. The root set is comprised of all objects reachable from root objects and all possible references found by examining the call stacks of every Cocoa thread.

As implied earlier, there are two types of reference between objects—strong and weak. A strong reference is visible to the collector, a weak reference is not.
 An important corollary is that simply because you have a strong reference to an object does not mean that that object will survive garbage collection, 
You can create a weak reference using the keyword __weak, or by adding objects to a collection configured to use weak references (such as NSHashTable and NSMapTable).

Enabling Garbage Collection
Garbage collection is an optional feature; you need to set an appropriate flag for the compiler to mark code as being GC capable. The compiler will then use garbage collector write-barrier assignment primitives within the Objective-C runtime. An application marked GC capable will be started by the runtime with garbage collection enabled.

There are three possible compiler settings:
No flag. This means that GC is not supported.
-fobjc-gc-only This means that only GC logic is present.Code compiled as GC Required is presumed to not use traditional Cocoa retain/release methods and may not be loaded into an application that is not running with garbage collection enabled.
-fobjc-gc This means that both GC and retain/release logic is present.Code compiled as GC Supported is presumed to also contain traditional retain/release method logic and can be loaded into any application.
You can choose an option most easily by selecting the appropriate build setting in Xcode, as illustrated in





Foundation Tools (like command line code)
In a Cocoa desktop application, the garbage collector is automatically started and run for you. If you are writing a Foundation tool, you need to start the collector thread manually using the function objc_startCollectorThread:
#import <objc/objc-auto.h>
int main (int argc, const char * argv[]) {
objc_startCollectorThread();
// your code
return 0;
}

You may want to occasionally clear the stack using objc_clear_stack() to ensure that nothing is falsely rooted on the stack. You should typically do this when the stack is as shallow as possible—for example, at the top of a processing loop.
You can also use objc_collect(OBJC_COLLECT_IF_NEEDED) to provide a hint to the collector that collection might be appropriate—for example, after you finish using a large number of temporary objects.


Finalizing objects
In a garbage-collected application, you should ideally ensure that any external resources held by an object (such as open file descriptors) are closed prior to an object’s destruction. If you do need to perform some you must ensure that there are strong 
Nib files
references to all top-level objects in a nib file (including for example, stand-alone controllers)—otherwise they will be collected operations just before an object is reclaimed, you should do so in a finalize method.
You can create a strong reference simply by adding an outlet to the File's Owner and connecting it to a top-level object

Triggering garbage collection
Cocoa automatically hints at a suitable point in the event cycle that collection may be appropriate.
The collector then initiates collection if memory load exceeds a threshold. Typically this should be sufficient to provide good performance. Sometimes, however, you may provide a hint to the collector that collection may be warranted—for example after a loop in which you create a large number of temporary objects. You can do this using the NSGarbageCollector method collectIfNeeded.

// Create temporary objects
NSGarbageCollector *collector = [NSGarbageCollector defaultCollector];
[collector collectIfNeeded];

Threading
Garbage collection is performed on its own thread—a thread is explicitly registered with the collector if it calls NSThread's currentThread method (or if it uses an autorelease pool). There is no other explicit API for registering a pthread with the collector.




Prune caches
The collector scans memory to find reachable objects, so by definition keeps the working set hot. You should therefore make sure you get rid of objects you don't need.

Avoid allocating large numbers of short-lived objects
Object allocation is no less expensive an operation in a garbage collected environment than in a reference-counted environment.

Compile GC-Only
In general, you should not try to design your application to be dual-mode (that is, to support both garbage collection and reference-counted environments). The exception is if you are developing frameworks and you expect clients to operate in either mode.

C++
In general, C++ code should remain unchanged: you can assume memory allocated from standard malloc zone. If you need to ensure the longevity of Objective-C objects, you should use CFRetain instead of retain.



Garbage collection offers some significant advantages over a manually reference-counted environment 
-simplifies the task of managing memory
-reduces the amount of code you have to write and maintain
-makes it easier to write multi-threaded code: you do not have to use locks to ensure the atomicity of accessor methods and you do not have to deal with per-thread autorelease pools
(Note that although garbage collection simplifies some aspects of multi-threaded programming, it does not automaticallymake your application thread-safe. For more about thread-safe application development, see Threading Programming Guide .)

Garbage collection does though have some disadvantages:
-application’s working set may be larger
-Performance may not be as good as if you hand-optimize memory management
-A common design pattern whereby resources are tied to the lifetime of objects does not work effectively under GC.
-You must ensure that for any object you want to be long-lived you maintain a chain of strong references to it from a root object, or resort to reference counting for that object.
-Not all frameworks and technologies support garbage collection

Performance
The performance characteristics of an application that uses garbage collection are different from those of an application that uses reference-counting
Garbage-collected application may have betterperformance, for example:
Multi-threaded applications may perform better with garbage collection because of better thread support;
Accessor methods are much more efficient (you can implement them using simple assignment with no locks);
Your application is unlikely to have leaks or stale references.

In other areas, however, performance may be worse:
-Allocation may be a significant consideration if your application allocates large numbers of (possibly short-lived) objects.
The working set may be larger—in particular, the overall heap can grow larger due to allocation outpacing collection.
The collector scans heap memory to find reachable objects, so by definition keeps the working set hot.This may be a significant consideration, particularly if your application uses a large cache.
The collector runs in a secondary thread. As such, a GC-enabled application will in almost all cases consume more CPU cycles than a reference-counted application.

source:-https://developer.apple.com/legacy/library/documentation/Cocoa/Conceptual/GarbageCollection/GarbageCollection.pdf

0 comments:

Post a Comment

About

Powered by Blogger.