Autorelease mechanism and release time

Source: Internet
Author: User

The autorelease mechanism is a good companion for iOS developers to manage object memory, and in MRC, invoking [obj autorelease] to delay the release of memory is a simple and natural thing; under arc, we can even not know that the autorelease system can manage the memory properly. And behind this, OBJC and compiler all help us do what, one to explore the next autorelease mechanism.

Overview

When a autorelease message is sent to an object, cocoa puts a reference to the object into the latest auto-free pool. It is still a legitimate object, so other objects within the scope defined by the auto-release pool can send messages to it. When the auto-free pool is freed, all managed objects in it receive a "relrease" message, and all objects in the pool are freed. Note that the same object can be called multiple times by the "Autorelease" method, and can be placed in the same "Autoreleasepool".
So introducing this automatic release pool mechanism, the object's "Autorelease" method instead of the "relrease" method can prolong its life cycle and release it directly to the current "Autorelreasepool".

iOS manages memory by reference count

OC is the "referring counting" (reference count) to manage memory, the object at the beginning of the allocation of memory (ALLOC) when the reference count is one, and then whenever there is a copy,retain when the reference count will be added one, The reference count will be reduced by one whenever it encounters release and Autorelease, and if the count of this object becomes 0, it will be destroyed by the system.
GC (Garbage Collection) is garbage collection, it is important to note that iOS does not have a garbage collection mechanism, only by reference counting to manage memory, which is actually the core of autorelease principle. Let's not confuse this approach with the garbage collection mechanism. However, many languages still have their own garbage collection mechanism, recommend an article about garbage collection (GC) three basic ways .

NSAutoreleasePool How to use

NSAutoreleasePool *pool=[[nsautoreleasepool alloc] init];
When the [pool autorelease] is executed, the system will make a memory release, release the Autorelease object, if there is no nsautoreleasepool, then the memory will not be released
Note that the object is not automatically added to the current pool, but instead sends a AUTORELEASE message to the object so that the object is added to the current pool management. When the current pool receives a drain message, it simply sends a release message to all objects it manages.

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];NSString* nsstring;char"Hello CString";nsstring = [NSString stringWithUTF8String:cstring];[pool drain];
Precautions

The scope of management of 1.NSAutoreleasePool is in nsautoreleasepool *pool = [[NSAutoreleasePool alloc]init]; with [pool drain];
2. At the entrance of the program, the main function calls NSAutoreleasePool so that NSAutoreleasePool is not called in the program, but is freed automatically when exiting. The new thread is best realized NSAutoreleasePool
3.NSAutoreleasePool is actually an object reference count automatic processor. NSAutoreleasePool can have multiple at the same time, its organization is a stack, there is always a stack top pool, that is, the current pool, each create a pool, the stack to press one, change the current pool for the new pool, and then every time to send a drain message to the pool , pop the pool at the top of the stack and change the current pool to the next pool in the stack.
4. If automatic Reference counting (ARC) cannot use autorelease pools directly, use @autoreleasepool{}, @autoreleasepool {} Higher efficiency than direct use of nsautoreleasepool. But both are applicable under the MRC.
5. In a non-GC reference counting environment, drain and release are the same, but in the garbage-collected environment, drain is used. (The difference between "release" and "drain" is that "drain" causes GC recycling in environments with GC, "release" is the reverse.) In a non-GC environment, however, the two are the same. The official statement is for program compatibility, should consider "drain" instead of "release". )

Autorelease principle

Now look at the code for the use of a single-layer autoreleasepool under the MRC:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];NSArray * array = [[[NSArray alloc] init] autorelease];[pool drain];
Autoreleasepoolpage

ARC, we use @autoreleasepool{} to use a autoreleasepool, and then the compiler overwrites it like this:

void *context = objc_autoreleasePoolPush();// {}中的代码objc_autoreleasePoolPop(context);

Both functions are a simple encapsulation of autoreleasepoolpage, so the core of the auto-release mechanism is this class.

Autoreleasepoolpage is a C + + implemented class

Autoreleasepool does not have a separate structure, but is composed of several autoreleasepoolpage in the form of a doubly linked list (corresponding to the parent pointer and the child pointer in the structure, respectively).
The autoreleasepool is corresponding to thread one by one (the thread pointer in the structure points to the current thread).
Autoreleasepoolpage each object will open 4096 bytes of memory (that is, the size of the virtual memory page), in addition to the above instance variables occupy space, the rest of the space is used to store the address of the Autorelease object.
The above ID *next pointer acts as a cursor to the top of the stack at the next location of the Autorelease object that the add comes in.
When a autoreleasepoolpage space is occupied, a new Autoreleasepoolpage object is created, the linked list is connected, and later the Autorelease object is added to the new page.
So, if there is only one Autoreleasepoolpage object in the current thread and many Autorelease object addresses are logged, memory such as:

, this page joins a Autorelease object will be full (that is, next pointer immediately to the top of the stack), it is necessary to do the above operation, set up the next Page object, and this page linked list after the connection is completed, The next pointer of the new page is initialized at the bottom of the stack (begin position), and then continues to add new objects to the top of the stack.
So, sending a autorelease message to an object is to add the object to the position of the current autoreleasepoolpage at the top of the stack where the next pointer is pointing.

Release time

Whenever a Objc_autoreleasepoolpush call is made, runtime add a Sentinel object to the current autoreleasepoolpage with a value of 0 (that is, nil), then this page becomes the following:

The return value of the Objc_autoreleasepoolpush is exactly the address of the Sentinel object, which is Objc_autoreleasepoolpop (Sentinel object) as the entry, and thus:
1. Locate the page where the Sentinel object is located, based on the address of the incoming Sentinel object.
2. In the current page, send the release message once for all Autorelease objects inserted later than the Sentinel object, and move the next pointer back to the correct position.
3, add 2: from the newest addition to the object has been clean up, you can move forward across a number of page, until the Sentinel page, just after the execution of the Objc_autoreleasepoolpop, and eventually become the following look:

Nested Autoreleasepool

But because you mentioned that each instance of the build might be larger. Nesting only outside the loop can cause 10,000 instances in memory to exist before the pool is released, resulting in an excessive amount of memory being consumed in an instant. Therefore, if each of your instances needs to be used only during a single cycle, consider creating a pool within a loop and releasing

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];for010000; i++){        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    ...    [pool drain];}[pool drain];

Know the above principle, nested autoreleasepool is very simple, pop time will always release to the last push position, multi-layered pool is more than Sentinel object, just like peeling onions, each layer, do not affect each other.

Autorelease Release Opportunity

Many people say that when a program executes at the end of a scope (at the end of the current scoped brace), the automatic release of the pool is released, which is not true. What is the right process?

The iOS runtime is made up of a single runloop, with a few steps that each runloop will perform:

As you can see, each runloop creates a autorelease Pool and releases it at the end of the Runloop, so in general, every object that accepts Autorelease messages is freed before the next Runloop begins. That is, during the execution of a synchronized code, the resulting object will generally not be released before the end of the scope after it accepts the autorelease message.
So strictly speaking, without manually adding the Autorelease pool, the Autorelease object is released at the end of the current runloop iteration, and it can be released because the system has automatically released pool push and pop in each runloop iteration.

Small experiment

__Weak IDReference =Nil;- (void) Viewdidload {[SuperViewdidload];NSString*STR = [NSStringstringwithformat:@"Sunnyxx"];//STR is a Autorelease object, set a weak reference to observe itreference = str;} - (void) Viewwillappear: (BOOL) Animated {[SuperViewwillappear:animated];NSLog(@"%@", reference);//Console:sunnyxx}- (void) Viewdidappear: (BOOL) Animated {[SuperViewdidappear:animated];NSLog(@"%@", reference);//Console: (NULL)}

Since this VC is add to the window level after Loadview, Viewdidload and Viewwillappear are called in the same runloop, so in Viewwillappear, The autorelease variable still has a value.
Of course, we can also manually intervene the release time of the Autorelease object:

- (void)viewDidLoad{    [super viewDidLoad];    @autoreleasepool {        NSString *str = [NSString stringWithFormat:@"sunnyxx"];    }    NSLog(@"%@"// Console: (null)}

Reference:autorelease principle Analysis

Autorelease mechanism and release time

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.