This paper mainly starts from the following aspects:

  1. Automatic release tank
  2. Cause of memory leak
  3. Memory problem detection method
  4. Optimization suggestions (startup, interface, Energy consumption, etc.)
  5. Application of weight loss (Part 2)

1. Automatically release the autoreleasepool pool

Autorelease is essentially delaying the call to the release terminal to execute the command clang-rewrite-objc main.m 65 warnings generated. No error, generate main. CPP c++ file, import into Xcode project.

Note that main. CPP is added to the project and target is not allowed to compile

The code at the bottom of main.cpp:

{ __AtAutoreleasePool __autoreleasepool; } struct __AtAutoreleasePool { __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush(); } constructor ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atAutoReleasepoolobj); } void * atAutoReleasepoolobj; };Copy the code

The __AtAutoreleasePool structure calls the constructor and destructor, which calls objc_autoreleasePoolPush and objc_autoreleasePoolPop

For those unfamiliar with constructors and destructors, here’s a simple example:

Enter the curly braces '{'“Will be calledThe constructorTo printTest()

The destructor is called when the braces ‘}’ are out, printing ~Test().

Objc_autoreleasePoolPush () is called when you enter curly braces ‘{‘

Objc_autoreleasePoolPop (atAutoReleasepoolobj) will be called when the curly braces ‘}’ are out

The atAutoReleasepoolobj object acts as a sentinel so that the object is released after the braces ‘}’

Download objC source code online, searchobjc_autoreleasePoolPush, through the terminal main. CPP and objc source code can be found the following three points:

  1. The main structures and classes of the automatic release pool are __AtAutoreleasePool and AutoreleasePoolPage

  2. Objects that call AutoRelease are ultimately managed through the AutoreleasePoolPage object

  3. AutoreleasePoolPage is 4096 bytes in size

Autorelease pool is a bidirectional list of linked pages, each page is 4096, the current page is full, will be added to the next page.

The AutoreleasePoolPage class itself occupies 56 bytes and has a capacity of 4096 bytes.

The following analysis of AutoreleasePoolPage due toarcCannot be called directlyautoreleaseMethod, so you need to remove arc, as shown below:

Extern void _objc_autoreleasePoolPrint(void);

Conclusion:

  1. AutoreleasePoolPage is created by AutoreleasePoolPageTwo-way linked listImplementation of the
  2. When the object calls the autoRelease method, theDeferred release objects are added to AutoreleasePoolPage
  3. Calling the POP method will call theObjects on the stack send release messages

1.1 Processing of large amounts of temporary data

NSArray *urls = <# An array of file URLs #>; For (NSURL * URL in urls) {@autoreleasepool {// It doesn't make much sense torelease memory on the heap after each call to fileContents, instead of waiting for all loops to run and memory to be high. NSError *error; NSString *fileContents = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; }}Copy the code

1.2 Automatic release of pool blocks in custom threads

-(void)myThreadStart:(id)obj {@autoreleasepool}} // other {NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadStart:) object:nil]; [myThread start]; }Copy the code

The stack memory is 512KB for the subthread, 8m for the simulator and 1m for the real machine. If a large number of temporary variables are generated in the for loop, the memory increase will block the main thread or the subthreads, and the phone will become more and more stuck until it crashes. Autoreleaspool releases variables on the stack in {} in a timely manner after each iteration. This is something that autoreleaspool cannot clean up and requires a POP to destroy the main thread of the current page. Thread plug

2. Causes of memory leaks

Circular reference 2. Strong reference 3. Non-oc object, no manual release

Memory leaks can cause 'memory collection failure' and can cause programs to flash back when memory grows to around 120MB (how much to refill later).Copy the code

Normal memory reclamation process

     ClassA* a = [ClassA new];
     a.b = [ClassB new];    
Copy the code

Abnormal memory reclamation process

     ClassA* a = [ClassA new];
     ClassB* b = [ClassB new];
     a.b = b;
     b.a = a;
Copy the code

Block loop reference:

Use __StrongSelf Typeof (self) = weakSelf to extend the life cycle of weakSelf object VC call POP, object has been released, delay callback when weakSelf is empty, Weakself. property causes the program to be uncontrollable and even flash back.

NSTimer circular reference

Either target-action or block execution of nstimer results in circular references. Block execution is initially released, but is immediately held again. Timer is run on runloop -> timer -> self

2.1 Using the call procedure, the proxy function invalidates the nstimer.

2.2 Middle class mode RunLoop -> custom timer -> Target (WeakSelf) -> self

2.3 Runtime dynamic add method: RunLoop -> timer -> target <– self
 self.target = [NSObject new];
class_addMethod([self.target class], @selector(fire), (IMP)fire, "v@:");

void fire()  {
    NSLog(@"%s", __func__);
}
Copy the code

After pop self releases,self.target does not hold self, and self.target also releases

2.4 use NSProxy

3. Memory problem detection method

Download code: github.com/tanghaitao/…

3.1 Static detection methods (wild pointer, manual Analyze, automatic)

3.1.1 Wild Pointers (Only OC Objects can be detected)

** Wild Pointers can only detect OC objects **, c language cannot detect the operation method:Edit Scheme -> Run -> Diagnostics– > checkZombie Objects, the effect is as follows: There is no check Zombie ObjectsRenderings of:

Check the Zombie ObjectsRenderings of:@property (assign, nonatomic) GVDataSource *dataSource; // The oc object assign will be released, and the pointer will still exist.

3.4 Static Analysis (Circular Reference Cannot be Detected)

Circular references could not be detected

3.4.1 track manually Analyze

The menu bar,Product-> Analyze.** First run, error, and then select the detection method **CGPathRef manual release, File close and other non-OC objects,

3.4.2 automatically Analyze

Build SettingsIn the searchAnalyze, is set toYesThe code is automatically parsed every time it is compiled or run

3.2 Dynamic Monitoring Methods (Instruments Third-party Tool Testing)

3.2.1 instruments

The code in the Instruments system is not accessible, it's not detectable, and it's sampled every once in a while, it's not 100% undetectable.

Filter the call chain display

3.2.2 Third-party Tool Detection (View and VC only)

MLeaksFinder limitation: Can only detect views and VC

Core: when the interface disappears completely and the state of the controller is out of the stack, observe whether the delayed observation object survives

3.3 dealloc