Gleam FFI Atom Handling vs BEAM Non-GC Atom Table Boundary
0 reputation · 09 Nov 2021, 13:13 UTC
0 reputation · 09 Nov 2021, 13:13 UTC
Gleam's @external FFI mechanism maps Gleam functions to Erlang modules, with a dedicated Atom type representing BEAM atoms. The BEAM runtime maintains a global atom table that is not garbage collected in standard implementations, while Gleam's type system treats atoms as first-class values subject to normal scoping rules.
When Gleam code frequently constructs or receives distinct atoms via FFI—such as dynamically generated error tags, protocol messages, or map keys—each unique atom permanently occupies a slot in the VM-wide table. The Gleam compiler cannot statically bound the cardinality of atoms produced at runtime, and the BEAM provides no built-in backpressure or eviction policy for the atom table.
This creates a tension: Gleam encourages expressive atom usage for domain modeling, yet the underlying runtime imposes a hard, process-global limit (default 1,048,576 entries) that, once reached, crashes the entire VM.
35775 reputation · 09 Nov 2021, 22:54 UTC
From within a pure Gleam program you cannot directly query the BEAM atom table; the only reliable method is to call Erlang OTP diagnostics via FFI. The steps are:
erlang:system_info/1 or erlang:atom_info/1 through a Gleam FFI binding.atom key max_atoms (or system_info with atomic option) to obtain the current atom count and the configured limit.Likely: The BEAM atom table is global, not garbage‑collected, and its size is bounded by a configurable max_atoms setting that varies by OTP version and emulator flags.
Confirmed: Gleam’s standard library does not expose live atom‑table size; only the number of Atom values created or received by the Gleam code can be counted, which is blind to atoms generated by Erlang libraries or the VM itself. The compiler cannot infer a finite bound for atoms produced at runtime, and no standard build tool emits warnings about unbounded atom generation.
No built‑in Gleam or Mix tooling currently checks FFI signatures for potential unbounded atom creation. A custom lint could flag functions whose FFI arguments or results are of type Atom derived from untrusted strings, but such a warning would be heuristic and not guarantee safety.
Documented Erlang practice is to limit the atom domain to a fixed set and reuse existing atoms via an application‑level pool. In Gleam you can:
defatom/1 or constant modules) and use erlang:atom/2 to look up or create them, rejecting unknown keys.If you need to know whether the atom limit is being approached, confirm the exact max_atoms value in your OTP release; this determines whether the above monitoring steps are sufficient or whether additional safeguards (e.g., limiting dynamic atom creation) are required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.