1. Thinking way of reference countingSelf-generated objects,Own Non-self-generated objects,I can hold it myself Not released when you need an object you own Objects not owned by you cannot be released
2. Implementation of reference counting
+ alloc + allocwithzone: class_creatinstance calloc
Calling the alloc method first calls the allocwithzone:class method, then the class_creatinstance function, and finally calls calloc to allocate a memory block.
-retaincount __cfdoexternrefoperation cfbasichashgetcountofkey
-retain __cfdoexternrefoperation cfbasichashaddvalue
-retaincount __cfdoexternrefoperation cfbasichashremovevalue //When cfbasichashremovevalue is 0, -release calls dealloc
Each method calls a series of functions with similar names through the same __cfdoexternrefoperation function.And it can be seen from the function name that Apple uses a hash table (reference count table) to manage reference counts.The table key value is a hash of the memory block address.However, gnustep stores the reference count in a variable (objc_layout) in the variable that the object occupies.
Benefits of memory block header management reference counting:Can be done with a small amount of code Ability to uniformly manage reference count memory blocks and object memory blocks.
Benefits of a reference technology table managing reference counting:
1. Object memory fast allocation without considering the memory block header
The memory block address is stored in each record of the reference count table.Traceability from individual records to individual memory blocks.
The second feature is important when debugging,Even if a failure causes damage to the memory block occupied by the object,But as long as the reference count table is not damaged,Can confirm the address of each memory block
nsautoreleasepool is implemented through a doubly linked list with autoreleasepoolpage as the node.autoreleasepoolpage is a class implemented in C++,The class structure is shown in the figure:magic is used to verify that the structure of autoreleasepoolpage is complete; next points to the next position of the newly added autoreleased object,Point to begin () during initialization; thread points to the current thread; parent points to the parent node,The parent value of the first node is nil; child points to the child node,The child value of the last node is nil; depth stands for depth,Start at 0 and increment by 1; hiwat stands for high water mark.
Each object of autoreleasepoolpage will open up 4096 bytes of memory (that is, the size of a page of virtual memory).All the remaining space is used to store the address of the autorelease object.The memory structure is shown in the figure:
In the cocoa framework, the nsautoreleasepool object is generated or discarded during each cycle of nsrunloop.When a large number of autorelease objects are generated, as long as the nsautoreleasepool is not discarded, the generated objects cannot be released.In this case, out of memory sometimes occurs,So it is necessary to generate it properly,Hold and discard nsautoreleasepool. Usually when using objective-c, no matter which object's autorelease/retain method is called, the implementation is to call the autorelease/retain instance method of the nsobject class.But for the nsautoreleasepool class, the autorelease/retain instance method has been rewritten,Therefore, an exception occurs at runtime. autorelease actually delegates the release timing of the object to nsautoreleasepool management, using the method as follows:
Generate and hold nsautoreleasepool objects.
nsautoreleasepool * pool=[nsautoreleasepool alloc] init];//equivalent to objc_autoreleasepoolpush ()
Call the autorelease instance method of the allocated object.
id obj=[nsobject alloc] init]; [obj autorelease];//equivalent to objc_autorelease () obj
Discard the nsautoreleaspool object (the release of the allocation object is automatically called).
[pool drain];//equivalent to objc_autoreleasepoolpop (pool)
The arc (automatic reference counting) is automatically retained/released during the compilation phase. The code that originally needed to manually add reference counting can be automatically completed by the compiler.arc is not gc, not runtime memory management,Will not do the work of malloc/free, it is just a static analysis tool (static analyzer) tool, in the same program, you can choose arc valid and invalid by file unit.In core foundation, malloc () or free (), etc., still need to manually perform memory management by themselves.The effective compilation method for setting arc is as follows:Use clang (llvm compiler) 3.0 or above. Specify the compiler property as "-fobjc-arc".
3. Reference count view
Apple provides methods to view the reference count of an object,However, the reference count values provided by these functions cannot be fully trusted.For an incorrect object address at the released object level,Sometimes it also returns "1". In multithreading,Because of race conditions,So the values obtained are not necessarily credible.
[object retaincount];//Get the reference count of the object,This method only works for mrc _objc_rootretaincount (obj);//both mrc and arc are applicable