| Did you know ... | Search Documentation: |
| Blobs and atom garbage collection |
A blob is reclaimed by the atom garbage collector, which is normally requested once agc_margin atoms have become candidates. An atom costs about fifty bytes, but a blob atom costs the same fifty bytes whether it references a small structure or a ten megabyte buffer, a compiled regular expression or a database handle. Counting atoms therefore says nothing about what is being kept alive: ten thousand blobs, well below the default margin, may hold gigabytes.
A blob type may declare a budget of its own in the gc_margin
field of its PL_blob_t. A blob counts towards this budget
with the len it was created with, so the unit is whatever len
means for the type: bytes for text and for copied blobs, and for
PL_BLOB_NOCOPY whatever the type chose to report (see
section
12.4.10.1). A type for which the scarce resource is the number of
live handles rather than their size, such as one wrapping a file
descriptor, passes 1 as len and sets gc_margin
to a number of instances.
static PL_blob_t my_blob =
{ PL_BLOB_MAGIC,
PL_BLOB_UNIQUE|PL_BLOB_NOCOPY,
"my_blob",
release_my_blob, compare_my_blob, write_my_blob, acquire_my_blob,
save_my_blob, load_my_blob,
0, /* padding */
16*1024*1024 /* gc_margin: collect per 16Mb */
};
The default, 0, leaves the type to agc_margin
alone, which is the behaviour of all types that do not set the field.
Setting
agc_margin to zero
disables atom garbage collection entirely and a type budget does not
override that.
Note that the budget is a request, not a bound: collection is
conservative and asynchronous, and a type whose blobs turn out to be
live stops requesting collections rather than repeating them,
as the survivors are discounted until another gc_margin of
candidates accumulates. As always, a type holding a critical resource
should offer an explicit predicate to dispose of it rather than relying
on the collector; see the release()
callback in section
12.4.10.1 and
PL_free_blob().
blob_type_property/2 reports the budget of a registered type, together with how far behind collection is for it, and set_blob_type/2 changes the budget at runtime.