spaceout package, which may be loaded by the
| ?- use_module(library(spaceout)).
contains the predicate:
call/1. If computing any solution causes the global stack usage to increase more than Space bytes, the goal will be aborted and Result unified with the atom
space_out. If the goal succeeds without exceeding that space limit, Result is unified with the atom
success. Space must be a positive integer.
Note that only the global stack usage is considered, i.e. the value
statistics(global_stack, [Used|_]) (see State Info).
space_out/3 is implemented by raising and handling memory
resource_error exceptions, so any exception handler in the scope
of Goal must be prepared to pass on such exceptions. Note that the
format of such exceptions varies depending on the execution mode,
Error and Exception Handling.
Before deciding whether to interrupt the computation a garbage
collection is performed to try to reduce the size of the global stack
enough to allow the computation to continue. As usual, garbage
collection can be prevented by setting the Prolog flag
off; see State Info.
%% Call foo/0 with space_out and do not allow GC. %% Ensure the gc flag is restored when we no longer need it %% By wrapping the goal foo in once/1 we ensure that call_cleanup %% will call the clean-up goal immediately when foo succeeds. ... Size is 10*1024, % 10kB prolog_flag(gc, OldGC), call_cleanup((set_prolog_flag(gc,off), space_out(once(foo), Size, Flag)), set_prolog_flag(gc,OldGC)), %% prolog_flag(gc, OldGC) will be true here ...
The precision of
space_out can be improved by calling explicitly
garbage_collect/0 before the call to
%% Call foo/0 with space_out ... Size is 10*1024, % 10kB garbage_collect, % ensure no garbage for foo/0 to use space_out(foo, Size, Flag), ( Flag == space_out -> write('foo used too much space'), nl ; write('foo used less than 10kB'), nl ), ...
A memory resource error triggered by a real out of memory
condition will not be caught by
The Goal will not be interrupted before the global stack has grown by Size bytes. However, the global stack may, under unusual circumstances, grow more than Space bytes before Goal is interrupted. Such growth is unlikely to exceed 10kB.