4.10.7.1 The Atom Garbage Collector User Interface

Because the creation of atoms does not follow any other system behaviors like memory growth or heap garbage collection, SICStus has chosen to keep the invocation of atom garbage collection independent of any other operation and to keep the invocation of atom garbage collection explicit rather than making it automatic. It is often preferable for the programmer to control when it will occur in case preparations need to be made for it.

Atom garbage collection is invoked automatically when the number of new atoms created since the last atom garbage collection reaches the value of the agc_margin flag.

Atom garbage collection can be invoked explicitly by calling garbage_collect_atoms/0. The predicate normally succeeds silently. The user may determine whether to invoke atom garbage collection at a given point based on information returned from a call to statistics/2 with the keyword atoms. That call returns a list of the form

     [number of atoms, atom space in use, atom space free]

For example,

     | ?- statistics(atoms, Stats).
     
     Stats = [4313,121062,31032]

One would typically choose to call garbage_collect_atoms/0 prior to each iteration of an iterative application, when either the number of atoms or the atom space in use passes some threshold, e.g.

     <driver loop> :-
             ...
             repeat,
                maybe_atom_gc,
                <do next iteration>
                ...
             fail.
     <driver loop>.

where

     maybe_atom_gc :-
             statistics(atoms, [_,Inuse,_]),
             atom_gc_space_threshold(Space),
             ( Inuse > Space -> garbage_collect_atoms ; true ).
     
     % Atom GC if there are more than 100000 bytes of atoms:
     atom_gc_space_threshold(100000).

More sophisticated approaches might use both atom number, atom space and agc_margin thresholds, or could adjust a threshold if atom garbage collection didn't free an adequate number of atoms.

To be most effective, atom garbage collection should be called when as few as possible atoms are actually in use. In the above example, for instance, it makes the most sense to do atom garbage collection at the beginning of each iteration rather than at the end, as at the beginning of the iteration the previous failure may just have freed large amounts of atom-rich global and local stack. Similarly, it's better to invoke atom garbage collection after abolishing or retracting a large database than to do so before.


Send feedback on this subject.