You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
5.1 KiB
Plaintext
127 lines
5.1 KiB
Plaintext
GCKit
|
|
=====
|
|
|
|
GCKit is a garbage collection kit designed for Objective-C. It is a hybrid collector, using a combination of reference counting, cycle detection, and tracing. The design goals are:
|
|
|
|
- Easy interoperability with non-GC code using retain/release semantics.
|
|
- Easy interoperability with code designed for Apple's GC implementation.
|
|
- Support for assisted reference counting with no compiler support.
|
|
- Support for automatic garbage collection with compiler support.
|
|
- Low overheads.
|
|
- Performance in memory-constrained conditions, without causing undue swapping
|
|
|
|
Memory Types
|
|
------------
|
|
|
|
There are three types of memory in GCKit's model:
|
|
|
|
- Objects
|
|
- Traced regions
|
|
- Untraced regions
|
|
|
|
Objects have a fixed layout and may contain strong, weak, and traced pointers.
|
|
|
|
Traced regions include the stack, and any regions explicitly designated for
|
|
tracing. Stacks are traced synchronously, from the thread that owns them,
|
|
while other regions are not.
|
|
|
|
Untraced regions are opaque to GCKit. They may contain pointers to GC'd
|
|
objects only if the pointers are manually reference counted using GCRetain()
|
|
and GCRelease().
|
|
|
|
Object Types
|
|
------------
|
|
|
|
GCKit will allocate two kind of memory. Objective-C objects, and buffers.
|
|
|
|
Reference Types
|
|
---------------
|
|
|
|
There are four kinds of reference (pointer) in GCKit's memory model:
|
|
|
|
- Strong.
|
|
- Zeroing weak.
|
|
- Traced.
|
|
- Invisible.
|
|
|
|
Strong references use reference counting. When an object is strongly assigned
|
|
to a pointer, its reference count is incremented and the reference count of the
|
|
old object is decremented. Objects will never be deleted as long as they have
|
|
a strong reference count greater than 0 and their references can not all be
|
|
accounted for by cycles.
|
|
|
|
Zeroing weak references are also reference counted, however they do not prevent
|
|
an object from being finalized. Zeroing weak references follow similar
|
|
assignment semantics to strong references. When an object is only referenced
|
|
by zeroing weak references, it will be finalized, but not freed. Subsequent
|
|
reads of zeroing weak pointers to the object will decrement its reference count
|
|
and it will be freed once this reaches 0.
|
|
|
|
Traced pointers do not perform any reference counting. All pointers on the
|
|
stack are traced, as are pointers in memory buffers explicitly allocated for
|
|
tracing. Objects with a reference count of 0 will not be freed until tracing
|
|
these regions determines that there are no unseen references to them.
|
|
|
|
Copying traced pointers between stacks directly is not supported. If a thread
|
|
somehow gets a reference to another thread's stack and copies a pointer then
|
|
the compiler will not generate a write barrier. This means that, if the two
|
|
threads' stacks are not traced in the right order relative to each other (50%
|
|
chance) and there are no locatable heap references to the object then it may be
|
|
freed.
|
|
|
|
Invisible pointers are outside regions that the garbage collector knows about.
|
|
Objects pointed to by these may be deleted if their reference count hits 0.
|
|
|
|
Interior pointers are not supported. A pointer to the start of an object or
|
|
managed buffer must be maintained
|
|
|
|
Object Deletion
|
|
---------------
|
|
|
|
Objects marked as using CoreFoundation semantics are deleted as soon as their
|
|
reference counts hit 0.
|
|
|
|
All other objects are marked as potential garbage once their reference count
|
|
drops to a value that is equal to the number of references that the cycle
|
|
detector can find. If A and B both hold strong references to each other, then
|
|
they are marked as potential garbage once their reference count hits 1.
|
|
|
|
Interfaces
|
|
----------
|
|
|
|
Writing pointers into traced heap memory requires a write barrier. The
|
|
objc_assign_strongCast function generates this barrier for a single write
|
|
(another function, as yet unwritten, will generate it for multiple writes).
|
|
|
|
Assignments to instance variables or globals must increment the strong
|
|
reference count of the new value and decrement the value of the old one. The
|
|
objc_assignIvar() and objc_assignGlobal() functions perform this for you.
|
|
|
|
If you are storing pointers in memory that is not managed by GCKit then you
|
|
must call the CGRetain() function on the pointer to prevent it from being freed
|
|
and the GCRelease() function when you are finished with it.
|
|
|
|
Degenerate Cases
|
|
----------------
|
|
|
|
Objects using the Core Foundation or OpenStep models may set a flag indicating
|
|
that they do not contain cycles (or, more accurately, that the programmer takes
|
|
responsibility for freeing cycles). In this case, GCKit will trace the stack,
|
|
catching bugs where you might have used -release instead of -autorelease, but
|
|
aside from that will not provide any benefits.
|
|
|
|
Objects may also be marked as having CF semantics. In this case, they will be
|
|
checked for cycles (unless explicitly marked as acyclic), but will be finalised
|
|
when their reference count hits zero and subsequently destroyed when their weak
|
|
reference count hits zero.
|
|
|
|
Finally, you can use traced memory for everything. Don't do this. GCKit is
|
|
designed to be efficient when only a relatively small proportion of allocated
|
|
memory needs to be traced.
|
|
|
|
Outstanding Bugs
|
|
----------------
|
|
|
|
Lots. Seriously, don't use GCKit yet. Cycles in traced memory are not yet
|
|
detected. Lots of GCKit is completely untested.
|