HHVM's user heap is managed primarily with reference counting. All types that
represent a user-visible value inherit from
HeapObject, which contains the value's
reference count, a HeaderKind that describes its type, some mark bits for use
by the garbage collector, and some padding bits available for type-specific
uses. HeapObjects are created with a reference count of 1, and this count is
incremented or decremented as references to it are created or destroyed.
When a HeapObject's reference count goes to 0, it is destroyed.
Two reference count values are special:
Uncounted
values live longer than a single Hack request, and have their lifetime managed
by other mechanisms.
Static
values are never freed once created. Together, these are called persistent
values, which is where the KindOfPersistent* DataType names come from.
Persistent values are allocated with malloc() and cannot refer to counted
values, which live in request-specific heaps and are allocated by HHVM's request
memory manager.
HHVM also has a mark-sweep garbage
collector that runs
as a backup for reference counting. HeapObjects will be freed by the garbage
collector if they are not reachable from the request's roots, for example when
the only references to them are part of a reference cycle. The collector
primarily lives in heap-collect.cpp and
heap-scan.h, with scanning
code
spread throughout various other files, situated with the types being scanned.
For information on annotations, see type-scan.h.