MRC manual memory management and ARC automatic memory management

MRC

Eleven years ago, the system used the reference count of an object to determine whether to destroy it or not, requiring the programmer to manually retain +1 or release-1: [objc release] is required to release the object when it is no longer used. The reference count of the object is -1. When the reference count of the object is 0, the value of the reference count of the object is -1. The system will destroy this object

Summary: Who creates who releases who references who manages

ARC

Eleven years later, the automatic management mechanism referenced in iOS5, called automatic reference counting, is a compiler feature. Like MRC, it uses reference counting to determine whether an object needs to be destroyed. ARC mode does not require manual retain Release autorelease. The compiler inserts a release autorelease in place

Memory layout

The five partitions

Stack area, heap area, global area, constant area, code area, in fact, in addition to the five areas there are kernel area and retention, for example, a phone with 4GB of memory, 3GB for the five areas and retention, and 1GB for the kernel area. Kernel area: area used by the system for kernel processing operations, retention area: reserved for the system to process nil, etc

Stack area of the stack

Stack is the system data structure and the corresponding process/thread is the only, from high address what data structure, starting with 0 x7 address space, the stack area generally allocated space at run time, the size is small, the storage is not flexible, but reading and writing of high efficiency, used to store a local variable, the parameters of the function, automatically by the compiler to allocate and release. No memory fragmentation is generated

Heap heap area

Heap is from low to high addresses extension data structure, discrete memory area, similar to the linked list, fifo, address space begin with 0 x6 class at run time, by the developers themselves allocation and release, and the content of the system will heap storage recycle and release, convenient and flexible data use is widespread, but need to manually manage memory, It is easy to generate fragments, and the reading speed is slower than the stack area. When accessing the memory of the heap area, it usually reads the pointer address of the stack area where the object is located through the object first, and then accesses the heap area through the pointer address

Global area/static area/BBS section

The global area is the memory space allocated at compile time, starting with 0x1. Calcium data remains during the execution of the program and is released at the end of the program. Uninitialized global/static variables are stored and reclaimed once initialized, and data is stored in the constant area

Constant area/data

Constants are allocated at compile time and released only at the end of the program to store initialized global/static variables

The code/text

Allocated by compile time to hold the code that the program runs. The code is compiled into binary and stored in memory in the code area of the program. At the end of the program, the system automatically releases and reclaims the data stored in the code section.

If the string assignment is in the constant area and the alloc/new/ formatted string is in the heap area, the alloc object is in the heap, but the object pointer address is in the stack area

Memory management scheme

There are three other types besides MRC Arc

  • Tagged Pointer: Processes small objects, such as NSNumber, NSDate, and String
  • Nonpointer_isa: a non-pointer TYPE of ISA that optimizes 64-bit addresses (a pointer of 8 bytes holds the rest of the bits for class-specific information such as the availability of associated objects, the weak table, etc.)
  • SideTabels: Hash tables with two main tables: reference counting and weak reference tables

Tagged Pointer

self.name = [NSString stringWithFormate:@"rhq"];

Self. taggedPointName = [NSString stringWithFormate:@" I am a good computer industry "];

TaggedPointName is a small object stored in the constant area. Originally, name was allocated to the heap in alloc, but because string is small, it is optimized by iOS to become NSTaggedPointerString, and there is a constant area. No memory management will be done on him retain and release

Small objects are apple’s optimization of objects like NSString and NSNumber in a 64-bit environment,

  • For NSString, if the string is a combination of numbers and English letters with a length less than or equal to 9, it will be treated as a small object type and stored in the constant area, which will be released only after the app runs.
  • _NSCFString is an NSString subclass created at run time. The reference count ➕1 is stored on the heap;
  • _NSCFConstantString: string constant, a compile-time constant with a large retainCount value that does not cause a reference count change, stored in the string constants area.

Underlying principles of Tagged Pointer

An object’s alloc is a retain on the new value and a release on the old value, while a small object does not perform a retain when performing the underlying objc_retain() if it is a small object. Similarly, a small object is evaluated when performing objc_release(). I don’t release it if it’s a small object

Small object pointer is no longer a simple address, but an address + value, namely a real value, a common variable, which can be read directly without the need for ARC to manage and release, so it takes up less space and saves memory. In the 64-bit address of a small object, the first four bits represent the type, the last four bits are used by the system to do some processing, and the middle 56 bits are used to store values. String constants are directly assigned @ “”, there is a constant area, directly read, faster than withFormate initialization

The strong and the copy

copy

Instance variables: A member variable is an instance variable if its data type is a class that can be instantiated

Objc_retain -> release the old value of copyWithZone; objc_retain -> release the old value of copyWithZone;

Copy attributes, namecopy = [name copy]; Objc_storeStrong ->objc_reatain exists and creates objc_release if it does not exist

strong

The property modified by strong is the same as the property copy: objc_storeStrong->objc_reatain exists and creates ->objc_release if it does not

objc_retain

Retain: check whether the class contains a custom retain method by using the function. If so, forward the message and call the custom retain method. If rootRetain is not called

rootRetain

  • Returns if it is a small type
  • If it is not a small object that has been optimized for nonpointer, run the hash table +1 operation. If it is a small object, run the dealloc process to determine whether it is being released. If it is being released, run the dealloc process to release the weak reference table and reference counting table.
  • If it is not being released, the regular reference count +1 is applied to Nonpointer ISA.
  • When you copy, you just call copyWithzone, and strong refers to +1 whereas when you copy an object, you copy the address, which also points to that memory, +1

Hash table

Extra_rc has only 8 bits (one byte) to store reference counts on the real machine. When the reference count overflows, half of the reference count is stored in EXTRA_RC of ISA and the other half in sideTable. If all reference counts are stored in sideTable, the hash table needs to be unlocked every time. The operation is time-consuming and consumes high performance. Therefore, the operation of 50/50 is to improve performance. A hash table is a multi-member hash table, with only 8 hash tables on a real machine and 64 hash tables on other machines

Why hash tables are used instead of array linked lists:

  • Array is easy to query, subscript can be, but add and delete trouble, array read fast, but not convenient storage
  • Linked lists: easy to add and delete, but slow to query (traversing the section header), fast to store, slow to read
  • Hash table: the essence is a hash table, a collection of array and linked list of the number of advantages, add, delete, change and check are more convenient, such as the zipper hash table is the most commonly used linked list

Release analysis

  • reallysetproperty->objc_release->release->root_release
  • First check if it is a small object. If it is a small object, return
  • If it is not Nonpointer ISA, operate -1 directly on the hash table
  • In the case of Nonpointer ISA, the reference count in EXTRA_RC is -1 and the EXTRA_RC state at that time is stored in CARRY
  • If carry is 0, the underflow flow is performed
  • Determines if half the reference count is stored in the hash table
  • If so, take the stored half of the reference count from the hash table, perform -1 and store it in extra_RC
  • If the EXTRA_RC has no value and the hash table is empty, then dealloc is automatically triggered

Dealloc analysis

  • _objc_rootDealloc->rootDealloc ->objc_dispose->objc_destructInstance
  • Return if it is a small object
  • Objc_dispose ->objc_destructInstance call c++ destructinstance if it is nonpointer and has a weak reference table, associated objects, c++ destructor, hash table (reference counting table) Delete the associated reference ->clearDeallocating Clears the weak reference table + hash table -> Free
  • If not, free releases the memory.

RetainCount analysis

RetainCount-> _objc_rootRetainCount->rootRetainCount Alloc creates an object that actually has a reference count of 0 and prints a reference count of 1 because of the underlying +1 processing that was done when retainCount was obtained

After alloc, the reference count in the extra_rc is still 0, and bits.extra_rc is 0, except that bits. Extra_rc returns with + 1, so the reference count is 1 at read time

So the object created by alloc has no retain and release, just bits. Extra_rc +1 when retainCount is read