How to detect memory leak in Obj-C? What do you know?
The ways I know of so far are as follows
, the Memory Leaks
· Alloctions
Analyse,
Debug, the Memory Graph
· MLeaksFinder
There are two types of leaked memory:
· Laek Memory is the Memory leaked when the Release operation is forgotten.
· Abandon Memory is a circular reference that cannot be freed.
The above five ways, in fact, the first four are more troublesome, need to constantly debug and run, the fifth is Tencent reading team produced, the effect is better
How to override setters and getter_.md for properties under MRC
setter
getter
Override dealloc
Circular references
The nature of circular references: multiple objects have strong references to each other that cannot be released for the system to reclaim. How do I solve circular references?
#####1. Avoid circular references by changing a strong reference to a weak reference. For example, when you use weak references to invoke object methods within a block, you can use two macros
It is also possible to use __block to modify variables. Under MRC, __block does not increase its reference count, avoiding circular references. Under ARC, __block modifiers are strongly referenced and cannot avoid circular references.
#####2. Manually disconnect circular references when appropriate.
Usually we use the first one.
(1) Delegate circular reference belongs to mutual circular reference
A delegate is a circular reference that is commonly used in iOS development. In general, when you declare a delegate, you have to use either a weak reference or a assign one. Of course, if you choose between a delegate or a delegate, you can only use the assign one. It is best to use weak in the ARC case because the weak-decorated variable automatically points to nil when freed, preventing the existence of wild Pointers
(2) NSTimer circular reference belongs to mutual circular use
Within the controller, create an NSTimer as its property. Since the timer is also strongly referenced to the controller object after it is created, this object and the timer reference each other circulatively.
How to solve it?
Here we can use manual disconnection: if the timer is not repeated, just invalidate the timer to nil in the callback method. If it is a repeat timer, invalidate it to nil at the appropriate location
(3) Block circular reference
A simple example:
Since the block will hold the object in the block, it will hold the object in the block, and if the object in the block holds the block, it will cause a circular reference. The solution is simply to use the __weak modifier self
Not all blocks cause circular references. Only be strong reference to the block can produce a circular reference While such as dispatch_async (dispatch_get_main_queue (), ^ {}), [UIViewanimateWithDuration: 1 Animations :^{}] These system methods, or blocks, are not attributes but temporary variables, called stack blocks
There’s another scenario whereblock
At the start of executionself
The object has not been released, and during execution,self
Was released because it was usedweak
Embellished, soweakSelf
He was released, and nowblock
In the accessweakSelf
Error (direction) may occurnil
Object messaging doesn’t crash, but it doesn’t work either.
For this scenario, you should use the __strong modifier on the object in the block so that the object is held for the duration of the block and is released after the block is executed.
What is a dangling pointer? What is a wild pointer?
Dangling pointer The memory that the pointer points to has been freed, but the pointer still exists, this is a dangling pointer or lost pointer
Wild pointer Any pointer that is not initialized is actually an wild pointer
Strong, Weak, assign, copy, __unsafe_unretain, __autoreleasing
Strong
The Strong modifier points to and holds the object, and the reference count of the modified object increases by one. The object will not be destroyed as long as the reference count is not zero. Of course you can destroy it by forcing the variable to be nil.
Weak
The weak modifier points to but does not hold the object, and the reference count does not increase by one. This property was operated on in Runtime, and no action is required and can be automatically destroyed. Weak is used to modify an object and is usually used to avoid circular references. Weak does not apply to basic data types.
assign
Assign is used to describe basic data types,
For example, NSInteger, CGFloat, stored in the stack, memory is not managed by the programmer. Assign can decorate objects, but there are problems.
copy
Keyword and strong like copy, copy to decorate with variable types of immutable objects nsstrings, NSArray, NSDictionary.
__unsafe_unretain
__unsafe_unretain is similar to weak, but when the object is freed, the pointer already holds the previous address, and the freed address becomes a zombie object. It is not safe to access the freed address.
__autoreleasing
Assigning an object to a variable with __autoreleasing is equivalent to calling the object’s autorelease method when ARC is invalid, essentially throwing it into the auto-release pool.
Do you understand the concept of deep copy and shallow copy? How to implement deep copy of collection class
In short:
For immutable, non-collection objects, copy is a pointer copy, mutablecopy is a content copy
2, for mutable non-collection objects, copy, mutablecopy is a copy of the content
3, for immutable array, dictionary, collection and other collection objects, copy is a pointer copy, mutablecopy is a copy of the content
For mutable array, dictionary, collection and other collection objects, copy, mutablecopy is a copy of the content
However, a copy of the contents of a collection object is only a copy of the object itself, but the elements inside the object are also a pointer copy. To copy an entire collection object, use the collection deep copy method. There are two methods:
(1) Use the initWithArray:copyItems: method and set the second argument to YES
(2) Archive and unarchive collection objects:
Principles to follow when using automatic reference counting
1. Retain, release, retainCount, and autorelease cannot be used.
2. You cannot use NSAllocateObject or NSDeallocateObject.
3. You must comply with the naming rules of the memory management method.
4. Call Dealloc without displaying.
5. Use @autoreleasepool instead of NSAutoreleasePool.
6. Do not use the NSZone.
7. An object variable cannot be a member of a C structure.
8. Show the conversion ID and void*.
Eight, can you briefly describe the implementation mechanism of Dealloc
Dealloc implementation mechanism is the focus of the content management part, to understand this knowledge point, for a full range of understanding of memory management is very necessary.
1.Dealloc call process
(1). _objc_rootDealloc()
(2). Next call rootDealloc()
(3) At this time, it will judge whether it can be released. The judgment is based on five main factors, namely whether there are the above five situations
NONPointer_ISA
weakly_reference
has_assoc
has_cxx_dtor
has_sidetable_rc
If any of the above five are present, the object_Dispose () method will be called to proceed to the next step.
In the absence of any of the previous five cases, the release operation, free() of the C function, can be performed.
Execution is complete.
2. The object_Dispose () call process.
(1). Call objc_destructInstance() directly.
(2). Then call free() of C function.
3. Objc_destructInstance () calls the process
(1). Check hasCxxDtor and call object_cxxDestruct() if there is C++ related content.
(2). If hasAssocitatedObjects exists, call object_remove_associations() and destroy the associated object.
Then call clearDeallocating().
(4). Execution is complete.
4. ClearDeallocating () calls the process.
(1). First execute sideTable_clearDellocating().
(2). Then execute weak_clear_NO_lock. In this step, the weak reference pointer pointing to the object will be set to nil.
(3). Next execute table.refcnT.eraser () to erase the reference count of the object from the reference count table.
(4). So far, the execution process of Dealloc ends.
Nine, what are the five areas in the memory?
First of all, as a developer, it is particularly important to have a learning atmosphere and a communication circle. This is my iOS development public account: Programming Daxin. No matter you are a small white or a big ox, you are welcome to enter.
Stack: the stack is automatically allocated and freed by the compiler. It holds function parameter values, local variable values, etc. It operates in a similar way to a stack in a data structure.
Heap: Usually allocated by the programmer to release, if the programmer does not release, the program may end by the OS. Note that this is not the same as a heap in a data structure, but is allocated like a linked list.
Global (static) area (static) : Global and static variables are stored in the same area, initialized global and static variables in one area, and uninitialized global and static variables in another adjacent area. – Released by the system after the program ends.
Literal constants: This is where constant strings are placed. The program is released by the system.
Program code area: store the binary code of the function body.
What are the default memory management keywords?
MRC
ARC
If you change it to a basic data type, assign.
11. Memory management scheme
TaggedPointer: Stores small objects such as NSNumbers. Get deeper into Tagged Pointer
NONPOINTER_ISA(non-pointer ISA): In 64-bit architecture, isa Pointers are 64 bits. In fact, only 30 bits are sufficient. To improve utilization, the remaining bits are used to store memory management data contents.
Hash table: complex data structure, including reference count tables and weak reference tables, implemented through the SideTables() structure, under which there are many SideTable data structures. SideTable contains spin locks, reference count tables, and weak reference tables. SideTables() is actually a hash table that calculates which sideTable the object’s reference count is in by its address.
The spin lock.
A spinlock is a “busy and waiting” lock. Suitable for light access. The reference count table and the weak reference table are actually a hash table to improve the lookup efficiency.
12. Memory layout
Stack (stack): Method calls, local variables, etc., are sequential and extend from higher to lower addresses
Heap: Objects allocated, such as alloc, are discrete and extend from low to high addresses, requiring manual control
Uninitialized data (BSS): uninitialized global variables, etc
Initialized data: initialized global variables, etc
Code snippet (text): Program code
The bytes used by long and char in 64-bit and 32-bit are different
Char: 1 byte (ASCII2=256 characters)
Char * (i.e., pointer variable) :4 bytes (32-bit addressing space is 2, i.e. 32 bits, i.e. 4 bytes. 8 bytes for 64-bit compilers.)
Shortint: The range of 2 bytes is -2 to >2, that is, -32768 to >32767
Int: four bytes ranging from -2147483648 to >2147483647
Unsignedint: 4 bytes
Long: four bytes. The value ranges from 9223372036854775808 to 9223372036854775807. The value is the same as that of int
Longlong: the value ranges from 9223372036854775808 to 9223372036854775807
Unsignedlonglong :8 bytes Maximum value: 1844674407370955161
Float: 4 bytes
Double: 8 bytes
Static, const, and sizeof keywords
The static keyword
A: Static is used for two main purposes. It is used to decorate a storage type as a Static storage type, and it is used to decorate a link property as an internal link property.
(1) Static storage type:
A static local variable defined within a function that is stored in the static area of memory, so that the value of the static variable is not destroyed even after the function is finished and can be used the next time the function is run.
A static variable defined outside a function — a static global variable whose scope can only be found in the file in which it was defined and cannot be referenced by another extern text.
(2) Internal link properties
A static function can only be used in the source file from which it is declared.
The const keyword
1. Declare constant variables so that the specified variable cannot be modified.
2. Modifies a function parameter so that it cannot be modified within the function. Such as
3. Modifies the return value of the function so that the return value cannot be modified.
The sizeof keyword
Sizeof is handled at compile time and cannot be compiled into machine code. The result of sizeof is equal to the number of bytes of memory occupied by the object or type. Sizeof returns a value of type size_t.
Variables: inta; Sizeof (a) is 4;
Pointer: int * p; Sizeof (p) is 4;
Array: intb.br deal [10]; Sizeof (b) is the sizeof the array, 4*10; intc[0]; Sizeof (c) equal to zero
Struct (inta; charch;) s1; Sizeof (s1) of 8 is related to the byte alignment of the structure.
When sizeof a structure, there are two principles:
Note: We cannot sizeof a bitfield member in a structure
Sizeof (void) is equal to 1
Sizeof (void *) is equal to 4
How to understand iOS memory management
It’s actually a combination of all three
1.TaggedPointer (for small object types like NSNumber)
2.NONPOINTER_ISA (64-bit)
* the first 0 or 1 indicates whether it isa pure address type isa pointer or a NONPOINTER_ISA pointer.
* Second, whether there are associated objects
* the third digit indicates whether there is C++ code.
* The next 33 bits represent the memory address pointed to
* There are flags with weak references next
* Next comes the tag of whether delloc or not…. , etc.
3. Hash table (reference count table, weak table)
On non-embedded 64-bit systems, there are 64 SideTables
* Each SideTable is mainly composed of three parts. Spin lock, reference count table, weak reference table.
* Global reference counts do not exist in the same table to avoid resource competition and solve efficiency problems.
* The concept of separate locking is introduced in the reference count table. Splitting a table into several parts and locking them separately can achieve concurrent operation and improve execution efficiency
What about the @dynamic keyword?
At sign dynamic means that the compiler is not going to help us automatically synthesize setters and getters. We need to implement it manually, and this is where we get to the idea of dynamically adding methods to Runtime.
What about the data structure of @AutoReleasepool?
For each pool that is created, a sentinel object is created at the head, and a next pointer is created at the top of the outermost pool. When the list is full, it is at the top of the list and points to the next list.
Is the __weak-modified variable registered with @autoreleasepool? Why is that?
The answer is yes. An __weak reference is a weak reference, and if it is not registered with @autoreleasepool, it will be destroyed after creation. In order to extend its life, it must be registered with @autoreleasepool to delay its release.
17. The implementation mechanism of Retain and Release?
1. Implementation mechanism of Retain
2. Implementation mechanism of Release.
The implementation mechanism of the two is similar. In general, the first layer hash algorithm is used to find the sideTable corresponding to the pointer variable. Then, through a layer of hash algorithm, we find size_t where the reference count is stored and add or subtract it. RetainCount is not fixed at 1, and SIZE_TABLE_RC_ONE is a macro definition that is actually an offset with a value of 4.
18. MRC (manual reference counting) and ARC(Automatic reference counting)
1, the MRC: alloc, retain, release, retainCount, autorelease, dealloc
2, the ARC:
*ARC is the result of collaboration between LLVM and Runtime
*ARC disallows manual calls to retain, release, retainCount, and autoRelease keywords
*ARC added weak, strong keyword
3. Reference count Management:
Alloc: After a series of function calls, the calloc function is called and the reference count is not set to 1
Retain: After two hashes, find the corresponding reference count, and then increment the reference count by 1(actually adding the offset)
Release: As opposed to retain, it hashes twice to find the corresponding reference count, and then subtracts the reference count by 1
4. Weak reference management:
* Add weak: add by hashing location lookup. If the array of weak references for the current object already exists in the lookup position, a new weak reference variable is added to the array. If not, a weak reference array is created and the weak reference variable is added to the array.
* What happens to the weak object when it is released? Clear the weak variable and set the point to nil. When an object is freed by Dealloc, dealloc’s internal implementation calls the function related to weak reference cleanup, which looks for the weak reference table based on the current object pointer, finds the array of weak references corresponding to the current object, and sets all the weak reference Pointers in the array to nil.
5. Automatic release pool:
Call objc_autoreleasePoolPop when the runloop is about to end and push in a new AutoreleasePool
AutoreleasePoolPage is a stack of nodes through the form of a two-way linked list, is one to one with the thread. The internal properties are parent, child, thread, and the next pointer to the next place on the stack that can be filled.
*AutoreleasePool
The compiler rewrites @autoreleasepool{} to:
* objc_autoreleasePoolPush: With the current next position set to nil, the sentinel object, and the next pointer pointing to the next pushable position, the multilevel nesting of AutoreleasePool, meaning that every objc_autoreleasePoolPush, is actually constantly inserting sentinel objects into the stack.
*objc_autoreleasePoolPop
:
Find the corresponding position based on the sentry object passed in. Send release messages to each object added since the last push. Roll back the next pointer to the correct location.
19. Under what circumstances does BAD_ACCESS occur?
This error is reported when a memory space that has been destroyed is accessed. The root cause is a dangling pointer that has not been released.
When is autoReleasePool released?
The App starts, apple registered in the main thread RunLoop two Observer, the callback is _wrapRunLoopWithAutoreleasePoolHandler ().
The first event monitored by the Observer is an Entry(about to enter the Loop), which calls _objc_autoreleasePoolPush() within its callback to create an automatic release pool. Its order is -2147483647, which has the highest priority, ensuring that the creation of the release pool takes place before any other callbacks.
The second Observer monitors two events: BeforeWaiting(ready to go to sleep) calls _objc_autoreleasePoolPop() and _objc_autoreleasePoolPush() releases old pools and creates new ones; BeforeWaiting(ready to go to sleep) calls _objc_autoreleasePoolPush() releases old pools and creates new pools; Call _objc_autoreleasePoolPop() when Exit(about to Exit the Loop) torelease the automatic release pool. The order of this Observer is 2147483647, which has the lowest priority, ensuring that its pool release occurs after all other callbacks.
Principles of ARC automatic memory management
* Self generated objects, own
* Non-generated objects can be held by themselves
* You need to release objects you hold when they are no longer needed
Objects not held by oneself cannot be released
22. What does ARC do in operation?
Weak is the key word. Weak-decorated variables can be automatically set to nil when the reference count is zero, obviously with runtime logic at work.
* To ensure backward compatibility, when ARC detects that an autorelease in a class function is followed by an retain at run time, instead of calling the object’s autoRelease method directly, it calls objc_autoreleaseReturnValue instead. Objc_autoreleaseReturnValue looks at the code that will be executed after the current method returns. If that code is going to perform the retain operation on the returned object, it sets a flag bit in the global data structure instead of performing the autorelease operation. If the method returns an automatic release object, and a method is called code to keep the object, so at this point not direct execution retain, but instead to execute objc_retainAoutoreleasedReturnValue function. This function detects the flag bit just mentioned, and if it has been set, does not perform the retain operation, setting and detecting the flag bit is faster than calling autoRelease and retain.
What ARC does at compile time
Depending on the context in which the code is executed, insert retain, release at the appropriate location
How is ARC’s retainCount stored?
There are 64 hash tables, according to the hash algorithm to find the location, without traversal, very fast
Hash tables (reference count tables,weak
Table)
-SideTables On a non-embedded 64-bit system, there are 64 SideTables
– Each SideTable consists of three parts. Spin lock, reference count table, weak reference table.
– The global reference counts do not exist in the same table to avoid resource competition and solve the efficiency problem.
– The concept of separate locking is introduced in the reference count table. A table is split into several parts and each part is locked to achieve concurrent operations and improve execution efficiency
Reference count table (hash table)
Through the address of the pointer, find the address of the reference count, greatly improve the search efficiency
Stored through the DisguisedPtr(objC_object) function and also searched through this function, so the loop traversal is avoided.
How to set a variable to nil if there is no strong reference to its __weak attribute?
The weak reference used – weak table. It’s also a hash table.
Weak pointer variables point to the address key, and all Pointers to that memory address are added to an array called Value. When the memory address is destroyed, all objects in the array are set to nil.
What is the difference between __weak and _Unsafe_Unretain?
Weak is a pointer variable that is set to nil by Runtime after the memory address to which it points is destroyed. _Unsafe_Unretain will not be set to nil, which is prone to dangling Pointers and crashes. But _Unsafe_Unretain is more efficient than __weak.