"C # sister and Objective-C aunt dialogue" (05) automatic release of pool-foreign aid from demolition team

Source: Internet
Author: User

C # sister:Memory cleanup is just as troublesome as demolition in life.

Aunt Objective-C:Yes, the split is not split, it occupies space, it should not be split, the program crashes

C # sister:To put it bluntly, the difficulty is not solved. In terms of determination, we can judge whether the memory is useless.

Aunt Objective-C:Yes, it's like demolition in real life. It's not difficult to dig a house. Just let the bulldozer come over. What's hard is to decide which house to dig... The answer is yes, and the answer is wrong.

C # sister:As an advertisement,. NET's garbage collection mechanism is quite good. Accurate judgment ~

Aunt Objective-C:Yes, but you have to pay the price. By checking obsolete objects during runtime, it is like relying on census to determine which houses are useless. It is achieved by regular traversal. After all, performance is affected, in addition, recycling is not as timely as possible.


C # sister:
Yes, garbage collection is actually two parts of work. One is "check", the other is "recycle", and the other is "check" to find houses that are not used by anyone, write the word "split" in a large circle on the wall. "Recycling" means to flatten the house marked with "Demolition" and combine the houses still in use to avoid fragmentation. It is also important that the program is suspended during the recycle process.


Aunt Objective-C:What is the international practice of word splitting ?~ The entire process seems very long. How can we ensure the performance?

C # sister:. NET runtime adopts many methods to improve efficiency.

First, it gives priority to the Census of areas with relatively large population flows. Large population flows mean that houses are more likely to be idle. This is mainly optimized by age generation. the space occupied by objects is increased by 1 after each Garbage Collector scan without being cleared. For example, if a house you bought in is found to be in use in the census, the aging will become 1. The Census may no longer check the house, because you have lived for at least two years, and the possibility of migration is lower, the garbage collector will focus on checking the houses new after the last census. Of course, after cleaning up the 0-generation house, there is not enough space, and the garbage collector will check the 1-or even 2-generation house.


Aunt Objective-C:
This is discrimination. No wonder I bought a house in Shanghai and didn't have an account. I used to be a 0-generation hacker.



C # sister:
No way. Who gives efficiency priority? Who cares about the fairness of our small people ~ The second way to improve the efficiency of the garbage collector is to reduce the number of census tasks, unless the memory occupied by the program exceeds the specification, or the system memory itself is not rich, it is not easy to conduct memory census these bad things. You think the Garbage Collector has been scanning for nothing. They also want to have a rest ~



Aunt Objective-C:
There are so many insider information about. NET garbage collection.


C # sister:
In a few minutes, don't you think about it. Who is going to demolish this year? Aunt Objective-C, is there no insider in Object Management?


Aunt Objective-C:
Well, yes, but it's quite a comparison ~ Because there is room for selection, I did not say that I used the "Retain, Release" statistics on the number of referenced objects to determine whether objects can be recycled, in this way, the professional name is "reference counting technology ". Today, I will continue to talk about the Auto Release Technology ".


C # sister:
Auto Release? It sounds very advanced, isn't it similar to my garbage collection.


Aunt Objective-C:
Much worse, it is still reference counting in essence. In fact, it is not automated, But it simplifies the logic and code. It's a foreign aid. Let's take the tragic House class as an experiment.

#import "House.h"
// First build an object that needs to be deleted
@implementation House
-(void) dealloc // Objective-C will automatically call this method when destroying objects
{
    NSLog (@ "House was demolished");
    [super dealloc];
}
@end

Aunt Objective-C: This unlucky House class only overloaded the method of dealloc, forgot it? This method is called when the house is demolished. Next execute the following code

int main (int argc, const char * argv [])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // Create an automatic release pool
    House * h1 = [[House new] autorelease]; // Add the generated object to the automatic release pool
    NSLog (@ "% lu", [h1 retainCount]); // The number of object references is 1
    NSLog (@ "Start to destroy the automatic release pool");
    [pool drain]; // Destroy the automatic release pool, and also destroy the objects in the automatic release pool, including the House object referenced by h1
    return 0;
}
Results of the


Aunt Objective-C: Look at it sentence by sentence, the first is

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
It sounds cool, automatic, and pool. In fact, it has no technical content. The principle is actually something similar to NSMutableArray. Its dealloc method has code to send a release message to all objects in the pool. , The dealloc method of the pool is executed, and the pool sends release to all objects. It's that simple.

As for [[NSAutoreleasePool alloc] init], which is equivalent to [NSAutoreleasePool new], it is the initialization object.

To put it plainly is to instantiate an object of class "NSAutoreleasePool"


C # sister: I think so, the NS you mentioned last time indicates the Cocoa class. This class is a slightly longer name. If you write it vertically, it may still stand tall. Unfortunately, it is lying on your stomach. Other class leaders are handsome ...


Aunt Objective-C: House * h1 = [[House new] autorelease] This sentence focuses on autorelease, which means adding an instance of House to NSAutoreleasePool. Can also be written like this

 

 House * h1 = [House new];
    [h1 autorelease];
This step just adds the object to the pool and does not reduce the reference, so when the retainCount is counted, it is still 1

Next last step

[pool drain]
Drain and release have similar meanings, that is, emptying / destroying the automatic release pool and destroying objects in the pool at the same time.

But it is actually inaccurate to say "destroy objects in the pool" here.

The accurate statement is to send release messages to the objects in the pool one by one. Look at the principle I just said.

Because after this step, the number of references in the pool is only reduced by 1 (that is, release is called). Whether it can be destroyed depends on whether the number of references is reduced to 0.

For example, look at the following example

int main (int argc, const char * argv [])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // Create an automatic release pool pool
    House * h1 = [[House new] autorelease]; // Add the generated object to the automatic release pool
    [h1 retain]; // Add a reference manually
    NSLog (@ "% lu", [h1 retainCount]); // The number of object references is 2
    NSLog (@ "Start to destroy the automatic release pool");
    [pool drain];
    // At this time, the object referenced by h1 was not destroyed and a memory leak occurred.
    NSLog (@ "Memory leaked:% @", h1);
    return 0;
}
Results of the


Because we manually added a reference to the object referenced by h1 through retain before, even if [pool drain] did not destroy the object

Therefore, Autorelease Pool does not help us to actually destroy the objects in the pool, just call release one by one for the objects in the pool.

Take a look at what is happening in memory in the form of pictures




C # sister: Look at it this way, the automatic release pool does not solve any problems? Don't we still need to manage the number of citations ourselves?


Aunt Objective-C: We really need to count the number of citations ourselves, but it can help us get rid of the messy release. It only needs to release the pool object, and the other objects are released accordingly.

int main (int argc, const char * argv [])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // Create an automatic release pool
    House * h1 = [[House new] autorelease];
    House * h2 = [[House new] autorelease];
    House * h3 = [[House new] autorelease];
    House * h4 = [[House new] autorelease];
    NSLog (@ "% lu,% lu,% lu,% lu", [h1 retainCount], [h2 retainCount], [h3 retainCount], [h4 retainCount]);
    // h1-h4 completed the historical mission after some operations
    [pool drain];
    return 0;
}
The above code is definitely more refreshing than the following

int main (int argc, const char * argv [])
{
    House * h1 = [House new];
    House * h2 = [House new];
    House * h3 = [House new];
    House * h4 = [House new];
    NSLog (@ "% lu,% lu,% lu,% lu", [h1 retainCount], [h2 retainCount], [h3 retainCount], [h4 retainCount]);
    // h1-h4 completed some historical missions after some calculations
    [h1 release];
    [h2 release];
    [h3 release];
    [h4 release];
    return 0;
}

C # sister: It seems that there are fewer release calls, but after all, there is no release flexibility. If it is a release, once the programmer decides that the object is not used, it can be released immediately, but the AutoreleasePool must wait for the final drain. To put it plainly is to extend the survival time of garbage and waste memory.


Aunt Objective-C: Not false at all, so on mobile devices such as iPhone and iPad, in order to save precious memory resources, it is not recommended to use the automatic release pool. Even if there are too many objects generated by the program running on the Mac, you can generate multiple releases or nested object pools to release the objects as soon as possible. For example, the following example

int main (int argc, const char * argv [])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int i;
    for (i = 0; i <1000000000; i ++)
    {
        House * h = [[House new] autorelease];
        if (i% 1000 == 0) // If there is no content in this if statement, all 1000000000 objects must be generated before they can be released
        {
            [pool drain];
            NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        }
    }
    [pool drain];
    return 0;
}
For example, in the above code, if there is no content in the if statement, all 1000000000 House objects must wait for all objects to be generated, and then be released when the program ends

Very large memory consumption

But if you add this if statement, every 1000 objects generated and destroyed once, the memory footprint is very small.

Hey, if a billion homes are really created this way, those developers must be mad. . .


C # sister:


Objective-C Auntie: After talking for a long time, I haven't said the most important usage of the automatic release pool.


C # sister: Most important? ? Do you think someone will patiently see our conversation in this place?


Aunt Objective-C: Hey, I just forgot. Maybe there are 1-2 people who can see this here with patience, most people have closed the webpage long ago. See the example below

#import "House.h"
// First create an object that needs to be deleted. House class
@implementation House
-(void) dealloc // Objective-C will automatically call this method when destroying objects
{
    NSLog (@ "House was demolished");
    [super dealloc];
}
-(NSString *) description
{
    NSString * desc = [[NSString alloc] initWithFormat: @ "The cheapest house in the world"];
    return desc;
}
@end
I modified the House class, added a description method, and returned an NSString object.

description is equivalent to the ToString () method in .NET. In fact, it is also defined by the base class NSObject. Subclasses can be overridden to return a string describing the class.

I re-description here and return NSString object, but how to destroy this NSString object? Who should be responsible for the release?

Obviously this work can only be done by a program that calls description


C # sister: Nonsense, if it is destroyed in the description, it will return a fart result


Objective-C Aunt: Look at the following example.

int main (int argc, const char * argv [])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    House * h1 = [[House new] autorelease];
    NSString * desc = [h1 description];
    NSLog (@ "% @", desc);
    [desc release];
    [pool drain];
    return 0;
}
It ’s not straightforward to use it like this

If you use autorelease in the description of House, for example, the code is modified to

NSString * desc = [[NSString alloc] initWithFormat: @ "The cheapest house in the world"];
return [desc autorelease];
Call House's description program can be more concise

int main (int argc, const char * argv [])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    House * h1 = [[House new] autorelease];
NSLog (@ "% @", [h1 description]);
    [pool drain];
    return 0;
}

C # sister: It seems to be dizzy today ⋯ ⋯ It feels more and more complicated ~~, it is really hard for programmers to manage memory ⋯ ⋯


Objective-C Auntie: I talked too much about technology today. Because there are no rules to restrict them, it feels like a mess. Next time there will be rules for memory management. As long as you follow a few simple principles, it is actually very simple. Wow next time. . .


-

Dear students, I have been learning Objective-C for a short time. Learning Objective-C is not for Mac and iPhone development, and it is not practical.
In fact, a C # user learns Objective-C study notes. The exact purpose of learning is to help me understand C #. After all, it is impossible to know the characteristics of so-called C # without comparison.
Please look at this thing critically. If you find conflicts with other articles, books, reviews, and materials, please try to refer to other articles. And leave me a message
I also invite all masters to actively shoot bricks, which I just use to build a house ~~~
"C # sister and Objective-C auntie conversation"

(01) Meet Objective-C-Greetings for the first meeting
(02) This is the class-Auntie's Dog
(03) NSString-Meet Dogs Again
(04) Basics of Garbage Recycling-The Relocation Team
(05) Automatic release pool-foreign aid from the demolition team

        To be continued

Related Article

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.