This article is based on the company’s project records of some content, also written for a long time, has not been sent
The problem
Common causes of memory leaks:
Block loop reference
Strong reference to the delegate
NSTimer used incorrectly
Notification or listener not removed
Typical example – Block circular reference
//1: Property: memory policy - strong reference, our general global UIView is strong reference @property (strong, nonatomic) LGPlusButtonsView *plusButtonsViewMain; / / 2: Loading _plusButtonsViewMain = [LGPlusButtonsView plusButtonsViewWithNumberOfButtons: 3 firstButtonIsPlusButton: YES showAfterInit:YES actionHandler:^(LGPlusButtonsView *plusButtonView, NSString *title, NSString *description, NSUInteger index) {if (1 == index) {[_plusButtonsViewMain hideButtonsAnimated:YES completionHandler:^{//action1: Now the VC has a strong reference to plusButtonsViewMain, A typical block loop references [self XXX];}];} else if (2 == index) {[_plusButtonsViewMain hideButtonsAnimated:YES completionHandler:^{ //action2 [self xxx]; }]; } }]; [self.rootView addSubview: _plusButtonsViewMain];Copy the code
Typical example – a strong reference delegate
Typical example – NSTimer used incorrectly
Typical example – Notification or listener not removed
Analysis of the demo
App runs, wait for a moment, after memory stability, continue to analyze the next operation:
The operating memory size depends on the device, so let’s take a look at the initial memory size: 42.3m
And then a continuous wave of page functionality without memory leaks: cloud resource modules, for example
See the memory map above:
The first red box marks the continuous entry and exit of cloud resource modules. There are two possibilities: one is that network resources are not fully loaded due to the rapid entry and exit. The arc system has a strategy to automatically release the memory, so it will not be reclaimed immediately after exiting.
The second red box indicates that after the operation is slowed down, the resource is fully loaded and the images displayed are all cached (for images loaded with imageNamed).
There is no memory leak. Here is the graph of memory consumption with memory leak:
This wave of operation is not fast entry and exit, but exit after full cache loading of resources. Look at the picture, the peaks and valleys are not so steep, there is a gentle period, which indicates that it is not fast entry and exit. However, the memory did not recover to the stable value. After several waves of operation, the memory kept climbing. Finally, the operation stopped and the memory stable period began. What does that mean?
1: module entry, network request, resource loading, UI rendering, etc., memory back to peak
2: Exit. The resource that can be released is released. The memory leak and subsequent resource release process cannot go, and the memory decreases but does not return to a stable value. Those that are not released will not be managed upon re-entry
3: repeat 1 and 2 above several times. Memory keeps climbing
Optimizing memory leaks
General block loop reference, Xcode automatically reminds: XXX, everyone has encountered
However, some Xcodes cannot be identified statically, so product-analyze and product-profile-Leaks are commonly used. Leaks checks in the specific Instruments, there are many online sources, so I won’t go into details here, but some things to note:
The call tree is a stack of leaky code called from the bottom up, with the top of the stack… ????????????
product-analyze
This system tool, an analysis, a lot of memory leaks, there are the following categories:
- Dead store
- Logic error
- Core Foundation/Objective – c
- Memory(Core Foundation/Objective – c)
- Memory error
- API Misuse(Apple)
Unused variables, initialization, illegal return values, etc. Xcode also has a powerful tool to check for such problems: Debug Memory Graph ???????????????????
The real problem is in the Memory(Core Foundation/ Objective-C) and Memory Error categories. Click on the Memory leak icon to see the flow logic of Memory leaks
I think the developed code, it is necessary to analyze, one is to improve the quality of the code, the second is to improve their coding rigorous ability
tool
It doesn’t help that some block loop references or strong reference proxies cause the object to be unable to be released are not visible. Therefore, further analysis is needed:
MLeaksFinder
FBRetainCycleDetector
FBRetainCycleDetector is a FaceBook product that is specifically designed for loop detection. This will not go into further detail. MLeaksFinder 1.0 has integrated the FBRetainCycleDetector.
Note: xcode10 for personal use, after integrating with MLeaksFinder, compiling error reported:
Multiple commands produce '/Users/xxt/Library/Developer/Xcode/DerivedData/Zxjx-dpyxnqyuorobwacwcqektxdxptrt/Build/Products/Debug-iphoneos/Hnxxt.ap p': 1) Target 'Hnxxt' has create directory command with output '/Users/xxt/Library/Developer/Xcode/DerivedData/Zxjx-dpyxnqyuorobwacwcqektxdxptrt/Build/Products/Debug-iphoneos/Hnxxt.ap P '2) That command depends on Command in Target 'Hnxxt': script phase "[CP] Copy Pods Resources"Copy the code
File-workspace settings-shared Workspace Settings:Build System: Legacy Build System
As a developer, it is particularly important to have a learning atmosphere and a communication circle. This is my iOS development public number: Programming Daxin, whether you are small white or big ox are welcome to enter. Let us progress together and develop together! (free to provide some of the main collection of free learning books advanced information!)
After the above is done, you can check for memory leaks page by page:
For the typical example above, the result would look like this:
This page has a memory leak, can not release