Saturday, July 19, 2014

Exploring Swift Memory Layout

Mike Ash:

It looks similar to an Objective-C object, but there's 16 bytes of metadata instead of just 8 as is the case for Objective-C. It turns out that it is an Objective-C object that can be inspected using the APIs in objc/runtime.h.

Joe:

The other 32-bit value in the reference count is the unowned reference count, which is incremented by unowned references. The object is destroyed when its strong reference count hits zero (which also decrements the unowned reference count), and deallocated when its unowned reference count hits zero. This allows the runtime to verify that unowned references don't dangle, while avoiding the full cost of a nil-ing weak reference.

Still, it seems like lot of memory used in each instance for reference counting, when most objects won’t have very high reference counts.

Update (2014-08-01): Mike Ash:

Swift memory layout for generics is completely straightforward. The values are laid out just as they are with non-generic types, even if it means that class instances change size. Optionals of reference types represent nil as all zeroes, just like we're used to in Objective-C. Optionals of value types append a byte to the end of the value to indicate whether or not a value is present. Protocol types take up 40 bytes of storage, with the last two pointers containing references to type metadata tables, and the rest available for storying the underlying value. If more than 24 bytes of storage is needed, the value is automatically placed on the heap, and a pointer to the allocation is stored instead.

Comments RSS · Twitter

Leave a Comment