preface

Short step without thousands of miles, not small streams into rivers and seas. Learning is like rowing upstream; not to advance is to drop back. I’m a hauler who drifts from platform to platform. Today is a detailed explanation of the memory management interview questions, I hope to pay attention to you. Without further ado, just go, see how much you can do.

How do I detect memory leaks in OBJ-C? Which ones do you know?

There are several ways I know of so far

  • Memory Leaks

  • Alloctions

  • Analyse

  • Debug Memory Graph

  • MLeaksFinder

The leaked memory includes the following two types:

  • Laek Memory is the Memory leaked by forgetting to Release.

  • Abandon Memory is a kind of Memory that can’t be freed and is referenced in a loop.

The above mentioned five ways, in fact, the first four are more troublesome, need to constantly debug the operation, the fifth is Tencent reading team produced, the effect

Better

How to override setters and getter_.md under MRC

Circular reference

The essence of circular references: multiple objects have strong references to each other and cannot be freed for the system to recycle. How to solve circular reference?

Delegate circular references are circular references to each other

Delegate is a circular reference that is commonly encountered in iOS development. A weak reference, or weak, is usually used when a delegate is declared

How to choose between assign and weak? MRC can only use assign, but ARC is the best way to use weak

The weak variable automatically points to nil when released, preventing wild Pointers

2. NSTimer circular references are circular references to each other

In the controller, create an NSTimer as its property, since the controller object is also strongly referenced after the timer is created, so the object and timing

The devices will loop through each other.

How to solve it?

Here we can use the manual break loop reference:

If the timer is not repeated, set timer invalidate to nil in the callback method.

If it is a repeat timer, set its invalidate to nil in the appropriate place

What is a dangling pointer? What is a wild pointer?

Dangling pointer

The memory to which the pointer points has been freed, but the pointer still exists. This is a dangling pointer or stray pointer

Wild pointer

Pointers that are not initialized are wild Pointers

Retain,copy,assign,weak,_Unsafe_Unretain

Strong

The Strong modifier points to and holds the object, and the reference count of the modifier object is increased by one. Not as long as the reference count for this object is not zero

Be destroyed. You can of course 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 is not incremented by one. This property is manipulated in the Runtime,

No processing required and can be self-destructed. Weak Is used to modify objects, mostly where circular references are avoided. Weak does not modify base data

Type.

assign

Assign is primarily used to modify basic data types,

For example, NSInteger and CGFloat are stored on the stack, and the memory is not managed by the programmer. Assign can be used to decorate objects, but there are questions

The topic.

copy

Keyword and strong like copy, copy to decorate with variable types of immutable objects nsstrings, NSArray, NSDictionary

On.

__unsafe_unretain

__unsafe_unretain is similar to weak, but after the object is released, the pointer already holds the previous address

As a zombie object, access to the freed address will be problematic, so it is not secure. __autoreleasing

Assigning an object to a variable with an __autoreleasing modifier is the same as calling the object’s autorelease method when ARC is invalid, essentially

It was thrown into the automatic release pool.

Do you understand the concept of deep copy and shallow copy? How to implement deep copy

In short:

For immutable non-collection objects, copy is a pointer copy and mutablecopy is a content copy

For mutable non-collection objects, copy and mutable lecopy are both copies of content

Copy is a pointer copy, and mutablecopy is a content copy of an immutable array, dictionary, or collection

For mutable arrays, dictionaries, collections, etc., copy, mutablecopy is a copy of content

However, copying the contents of a collection object is just copying the object itself, but copying the elements inside the object is still pointer copying. You want to copy the whole

Collection object, we need to use the collection deep copy method, there are two ways:

Principles to follow when using automatic reference counting

  • Cannot use retain, release, retainCount, autorelease.

  • Do not use NSAllocateObject or NSDeallocateObject.

  • The naming conventions for memory management methods must be followed.

  • Dealloc is called without display.

  • Use @Autoreleasepool instead of NSAutoreleasePool.

  • NSZone cannot be used.

  • Object variables cannot be used as C language structure members.

  • Displays the transformation ID and void*.

Can you briefly describe the implementation mechanism of Dealloc

The Dealloc implementation mechanism is the focus of the content management section, to understand this point, for the full understanding of memory management is just very

It is necessary.

1.Dealloc invokes the flow

  • 1. First call _objc_rootDealloc()

  • 2. Next call rootDealloc()

  • 3. At this time, they will judge whether they can be released based on five main criteria

    • NONPointer_ISA
    • weakly_reference
    • has_assoc
    • has_cxx_dtor
    • has_sidetable_rc
  • 4-1. If any of the above five methods exists, the object_Dispose () method is called for further processing.

  • 4-2. If there is no one of the previous five cases, then the free operation can be performed, the C function free().

  • 5. No further action is required.

2. Object_dispose () invokes the process.

  • 1. Direct call

Objc_destructInstance ().

  • 2. Then call the C function free().

3. Objc_destructInstance () calls the process

  • 1. Check hasCxxDtor. If there is C++ related content, call object_cxxDestruct() to destroy C++

Related content.

  • If hasAssocitatedObjects exists, call object_remove_associations().

A sequence of operations that destroy an associated object.

  • 3. Then call clearDeallocating().

  • 4. The execution is complete.

4. ClearDeallocating () calls the process.

  • 1. Start with sideTable_clearDellocating().

  • 2. Perform weak_clear_NO_lock. In this step, the weak reference pointer to the object is set to nil.

  • 3. Next run table.refcnt.eraser () to erase the reference count for this object from the reference count table.

  • 4. The Dealloc execution process is complete.

Eight, what are the five areas in memory?

  • Stack: Automatically allocated by the compiler to hold function parameter values, local variable values, etc. It operates like this

Stacks in data structures.

  • Heap: Usually allocated and released by the programmer. If not released by the programmer, the program may be reclaimed by the OS at the end of the program. Pay attention to it and

Heaps in data structures are different things, but are allocated in a similar way to linked lists.

  • Global area (static area) (static) : global variables and static variables are stored together, initialized global variables and static

Variables are in one area, uninitialized global variables and uninitialized static variables are in another area adjacent to each other. – After the procedure

Released by the system.

  • Text constant area: This is where constant strings are placed. The program is released by the system after completion.

  • Program code area: The binary code that holds the function body.

What is the default keyword for memory management?

X. Memory management scheme

  • TaggedPointer: Stores small objects such as NSNumber. Understand Tagged Pointer

  • NONPOINTER_ISA(non-pointer ISA): In 64-bit architecture, the ISA pointer is 64 bits, which is actually only 30 bits long

This is enough. To improve utilization, the remaining bits are used to store data content related to memory management.

  • Hash table: Complex data structure, including reference count tables and weak reference tables

SideTables() implements the SideTables() structure, which contains a number of data structures.

SideTable contains spin locks, reference counting tables, and weak reference tables.

SideTables() is actually a hash table that uses the address of the object to calculate which sideTable the object’s reference count is in.

The spin lock.

  • Spin locks are “busy waiting” locks.

  • Suitable for light access.

The reference count table and the weak reference table are actually hash tables to improve lookups.

11. Memory layout

  • Stack: method calls, local variables, etc., are continuous, extending from high address to low address

  • Heap: an object allocated by alloc, etc., that is discrete and needs to be manually controlled from low address to high address

  • Uninitialized data (BSS): uninitialized global variables, etc

  • Initialized data: initialized global variables, etc

  • Code snippet (text): Program code

2. The number of bytes used for long and char is different in 64bit and 32bit

  • Char: 1 byte (ASCII2 = 256 characters)

  • Char * (pointer variable) :4 bytes (32-bit addressing space is 2, 32 bits, 4 bytes). with

64-bit compiler for 8 bytes)

  • Short int: 2 bytes range from -2 to > 2, that is, -32768 to >32767

  • Int: 4 bytes range from -2147483648 to >2147483647

  • Unsigned int :4 bytes

  • Long: 4-byte range: the same as int 8-byte 64-bit range: -9223372036854775808 to 9223372036854775807

  • Long Long: 8 bytes range from 9223372036854775808 to 9223372036854775807

  • Unsigned long Long :8 bytes Maximum value: 1844674407370955161

  • Float: 4 bytes

  • Double: 8 bytes

Static, const, and sizeof keywords

The static keyword

A: Static is used to modify the storage type to Static, and to modify the link property

It becomes the internal link property.

  • Static storage type:

A static local variable defined within a function that exists in a static area of memory, so that the value of the static variable does not occur even after the function is finished running

Destroyed, the function can use this value again the next time it is run.

A static variable defined outside a function – a static global variable whose scope can only be found in the file in which the variable is defined

The file is referenced via extern.

  • 2. Internal link attributes

A static function can only be used in the source file in which it is declared. The const keyword

The sizeof keywordSizeof is processed at compile time and cannot be compiled to 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.

12, talk about iOS memory management understanding

It’s actually a combination of all three

1.TaggedPointer (for small object types like NSNumber)

2.NONPOINTER_ISA (on 64-bit systems)

  • The first 0 or 1 represents a pure address TYPE ISA pointer or a NONPOINTER_ISA pointer.

  • The second, represents whether there is an associated object

  • The third digit indicates whether there is C++ code.

  • The next 33 bits represent the memory address to point to

  • Next comes a flag with weak references

  • Next there is a flag whether delloc is available…. , etc.

3. Hash table (reference count table, weak table)

  • On non-embedded 64-bit systems, there are 64 SideTables

  • Each SideTable consists of three main parts. Spin locks, reference count tables, weak reference tables.

  • The reason why global reference counts are not in the same table is to avoid resource competition and solve the problem of efficiency.

  • The concept of separate locking is introduced in reference counting table, which can realize concurrent operation by splitting a table into multiple parts and locking them separately

To improve the execution efficiency

What about @dynamic?

At sign dynamic means that the compiler is not going to help us compose setter and getter methods automatically. We need to implement it manually, which is covered here

Add method to Runtime dynamically.

What is the @autoreleasepool data structure?

Each linked list ends with a parent pointer and a child pointer

Each time a pool is created, a sentinel object is created at the head as a marker

There will be a next pointer at the top of the outermost pool. When the list is full, it’s at the top of the list and points to the next list.

Is the __weak modifier already registered in @autoreleasepool? why

? The answer is yes, __weak modified variables are weak references, and if they are not registered with @Autoreleasepool, they will be

To extend its life, it must be registered with @Autoreleasepool to delay its release.

Implementation mechanism of retain and release?

MRC (Manual Reference Counting) and ARC(Automatic Reference Counting)

* * 1, MRC: alloc, retain, release, retainCount, autorelease, dealloc * * 2, ARC:

  • ARC is the result of a collaboration between LLVM and Runtime

  • ARC disallows manual calls to the retain, Release, retainCount, autoRelease keywords

  • ARC added weak, strong keywords

3. Reference count management

  • Alloc: After a series of function calls, the calloc function is finally called without setting the reference count to 1

  • Retain: Find the reference count value after two hashes and increment the reference count by one

  • Release: As opposed to retain, the reference count value is found after two hash loots and the reference count is subtracted by one

4. Weak reference management:

  • Add weak variable: Add by hashing algorithm location lookup. If there is already a weak reference to the current object in the corresponding position

Array, add the new weak reference variable to the array; If not, an array of weak references is created and the weak reference variable is passed

Add to the array.

  • What happens to the weak object when it is released?

Clear the weak variable and set pointing to nil. Weak is called in the internal implementation of dealloc when the object is released by dealloc

Reference to clear the relevant function, according to the current object pointer to find the weak reference table, find the current object of the corresponding weak reference array, the number

All weak reference Pointers in the group are set to nil.

5. Automatic release pool:

Call objc_autoreleasePoolPop when the second runloop is about to end and push in a new AutoreleasePool

AutoreleasePoolPage is a stack node combined in the form of a bidirectional linked list, which is thread – specific.

The internal attributes are parent, child, thread, and next to the next fillable position on the stack.

  • How does AutoreleasePool work?

The compiler will rewrite @autoreleasepool {} to:

  • Objc_autoreleasePoolPush:

Set the current next position to nil, the sentinel object, and then the next pointer to the next pluggable position,

The multiple layers of nesting of AutoreleasePool, each objc_autoreleasePoolPush, are essentially constantly inserting sentinels into the stack

Object.

  • objc_autoreleasePoolPop:

Find the corresponding position based on the incoming sentry object.

Send release messages to the objects added after the last push operation.

Roll back the next pointer to the correct position.

When 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 will autoReleasePool be released?

The App starts, apple registered in the main thread RunLoop two Observer, the callback is _wrapRunLoopWithAutoreleasePoolHandler (). 

  • The first Observer looks at Entry(about to enter Loop), which creates an automatic release pool with a call to _objc_autoreleasePoolPush() within its callback. Its order is -2147483647, the highest priority, ensuring that the release pool is created before all other callbacks.

The second Observer looked at two things:

BeforeWaiting(Ready standby enters sleep)

_objc_autoreleasePoolPop() and _objc_autoreleasePoolPush() release old pools and create new ones; The Exit (i.e.

To exit Loop), call _objc_autoreleasePoolPop() torelease the automatic release pool. The order of this Observer

Is 2147483647, the lowest priority, ensuring that its release pool occurs after all other callbacks.

ARC automatic memory management principles

  • Self generated objects, own

  • Objects that are not generated by themselves can be held by themselves

  • You need to release the objects you hold when they are no longer needed

  • Objects that are not owned by you cannot be released

What does ARC do at runtime?

  • Mainly refers to the weak keyword. Weak variables can be automatically set to nil when the reference count is 0, which is obviously lucky

Line time logic at work.

  • To ensure backward compatibility, ARC detects an autorelease in a class function at runtime followed by retain

Instead of calling the object’s autoRelease method directly, call objc_autoreleaseReturnValue instead.

Objc_autoreleaseReturnValue will view the code that will be executed after the current method returns, if that code

To perform a retain operation on a returned object, set a flag bit in the global data structure instead of performing an autorelease

Operation, similarly, if the method returns an automatically freed object and the code calling the method wants to preserve the object

No direct execution retain, but instead to execute objc_retainAoutoreleasedReturnValue function. This letter

The number checks for the flag bit mentioned earlier. If the bit is already set, the retain operation is not performed. Setting and checking the flag bit is better than the call

Autorelease and retain are faster.

What does ARC do at compile time

Insert retain, release 23 in the appropriate place, depending on the code execution context.

There are 64 hash tables, according to the hash algorithm to find the location, no traversal, very fast

Hash table (reference count table, weak table)

-SideTables There are 64 SideTables on non-embedded 64-bit systems

– Each SideTable consists of three main parts. Spin locks, reference count tables, weak reference tables.

– The global reference count does not exist in the same table to avoid resource competition and solve the efficiency problem.

– The concept of separate locks is introduced in reference count tables. Separate a table into multiple parts and lock them separately to achieve concurrent operations.

Improve execution efficiency

The reference counter table (hash table) searches for reference counter addresses based on pointer addresses, greatly improving the search efficiency

The DisguisedPtr(objC_object) function is stored and also searched through this function, thus avoiding loop traversal.

24. How to set a variable modified by an __weak attribute to nil if it is not strongly referenced?

Weak reference – Weak table used. It’s also a hash table.

The weak pointer pointer to the address is key, and all Pointers to the memory address are added to an array.

This array is 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

The weak pointer variable is set to nil by the Runtime mechanism after the memory address it points to is destroyed.

_Unsafe_Unretain will not be set to nil, which is prone to dangling Pointers and crashes. But _Unsafe_Unretain than

__weak High efficiency.

The next period will be broken down in detail

Six design principles in programming?

How to design a picture caching framework?

3. How to design a statistical framework for time?

For detailed answers and interview materials, please click ## to get the materials