This paper mainly starts from the following aspects:
- Automatic release tank
- Cause of memory leak
- Memory problem detection method
- Optimization suggestions (startup, interface, Energy consumption, etc.)
- 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 constructor
To 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:
-
The main structures and classes of the automatic release pool are __AtAutoreleasePool and AutoreleasePoolPage
-
Objects that call AutoRelease are ultimately managed through the AutoreleasePoolPage object
-
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 toarc
Cannot be called directlyautorelease
Method, so you need to remove arc, as shown below:
Extern void _objc_autoreleasePoolPrint(void);
Conclusion:
- AutoreleasePoolPage is created by AutoreleasePoolPage
Two-way linked list
Implementation of the - When the object calls the autoRelease method, the
Deferred release objects are added to AutoreleasePoolPage
- Calling the POP method will call the
Objects 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 Objects
Renderings of:
Check the
Zombie Objects
Renderings 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 Settings
In the searchAnalyze
, is set toYes
The 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