What does a class instance look like in memory?

3.4.1 · L3 · Learning

Predict first

What sizes does the runtime report, in bytes?

import ObjectiveC

final class Empty {}
final class One { var a = 0 }
final class Two { var a = 0; var b = true }
print(class_getInstanceSize(Empty.self), class_getInstanceSize(One.self), class_getInstanceSize(Two.self))
  • 0 8 9
  • 16 24 25
  • 16 24 32

Mental model. Every object arrives in a box with a 16-byte shipping label on the front. The label says what it is and how many people hold it.

A Swift class instance is a heap block that starts with a 16-byte header: a pointer to the type’s metadata (which gives the runtime its class, vtable and layout), and a word holding the inline reference counts. Your stored properties follow, laid out in declaration order with the usual alignment padding. An empty class is 16 bytes; add an Int and it is 24; add a Bool as well and it rounds up to 32, not 25.

That header is why a class costs more than a struct holding the same fields: 16 extra bytes, an allocation (malloc), reference-count traffic on every copy, and an indirection to reach the data. MemoryLayout measures structs; for a class, class_getInstanceSize (from ObjectiveC) reports the instance size, and MemoryLayout<SomeClass>.size is only the 8-byte reference.

The 16-byte header, plus 8 for the Int, plus 1 for the Bool, rounded up to the next 8: 32.

Common traps

  • Using MemoryLayout<MyClass>.size to size an object. That is the pointer, always 8 bytes. Use class_getInstanceSize.
  • Adding up field sizes. Alignment rounds the total: 8 + 1 on top of the header becomes 32, not 25.

They might follow up with

  • What is in the second header word? The strong and unowned counts plus flags. See the side-table question.
  • Does a subclass add another header? No. It appends its own fields after the superclass’s.

Related questions

  • 3.4.2 What do MemoryLayout’s size, stride and alignment mean, and why does field order matter?
  • 3.4.4 What is a side table, and when does the runtime create one?
  • 3.4.3 What actually allocates on the heap in Swift, and how do you see it?

What do MemoryLayout’s size, stride and alignment mean, and why does… →