Up Next

19.1  Introduction

This chapter may be skipped on a first reading. Its purpose is to give the advanced user a better understanding of how the system uses memory resources. In a high level language like Prolog it is often not obvious for the programmer to see where the system allocates or frees memory.

The sizes of the different memory areas can be queried by means of the predicate statistics/2 and statistics/0 prints a summary of all these data. Here is a sample output:
[eclipse 1]: statistics.

times:                  [1.12, 0.09, 2.74] seconds
session_time:           2.74 seconds
event_time:             2.74 seconds
global_stack_used:      1936 bytes
global_stack_allocated: 4456448 bytes
global_stack_peak:      4456448 bytes
trail_stack_used:       64 bytes
trail_stack_allocated:  262144 bytes
trail_stack_peak:       4456448 bytes
control_stack_used:     564 bytes
control_stack_allocated:262144 bytes
control_stack_peak:     262144 bytes
local_stack_used:       492 bytes
local_stack_allocated:  262144 bytes
local_stack_peak:       262144 bytes
shared_heap_allocated:  1613824 bytes
shared_heap_used:       1411000 bytes
private_heap_allocated: 73728 bytes
private_heap_used:      36992 bytes
gc_number:              1 
gc_collected:           23472.0 bytes
gc_area:                23560 bytes
gc_ratio:               99.6264855687606 %
gc_time:                0.0 seconds
dictionary_entries:     3252 
dict_hash_usage:        2117 / 8192 
dict_hash_collisions:   314 / 2117 
dict_gc_number:         2 
dict_gc_time:           0.01 seconds
The used-figures indicate the actual usage at the moment the statistics built-in was called. The allocated value is the amount of memory that is reserved for this area and actually occupied by the ECLiPSe process. The peak value indicates what was the maximum allocated amount during the session. In the following we will discuss the six memory areas mentioned. The gc-figures are described in section 19.2.

19.1.1  The Shared/Private Heap

The heap is used to store a variety of data: Note that the distinction between shared and private heap is only relevant for parallel ECLiPSe systems, where multiple workers share the shared heap, but have their own private heap and stacks.

19.1.2  The Local Stack

The Local Stack is very similar to the call/return stack in procedural languages. It holds Prolog variables and return addresses. Space on this stack is allocated during execution of a clause and deallocated before the last subgoal is called (due to tail recursion / last call optimisation). This deallocation can not be done when the clause exits nondeterministically (this can be checked with the debugger or the profiling facility). However, if a deallocation has been delayed due to nondeterminism, it is finally done when a cut is executed or when execution fails beyond the allocation point. Hence the ways to limit growth of the local stack are

19.1.3  The Control Stack

The main use of the Control Stack is to store so-called choicepoints. A choicepoint is a description of the system's state at a certain point in execution. It is created when more than one clause of a predicate apply to a given goal. Should the first clause fail, the system will backtrack to the place where the choice was made, the old state will be restored from the choicepoint and the next clause will be tried. Disjunctions (;/2) also create choicepoints.

The only way to reduce Control Stack usage is to avoid unnecessary nondeterminism. This is done by writing deterministic predicates in such a way that they can be recognised by the system. The debugger can help to identify nondeterministic predicates: When it displays an *EXIT port instead of EXIT then the predicate has left a choicepoint behind. In this case it should be checked whether the nondeterminism was intended. If not, the predicate can often be made deterministic by

19.1.4  The Global Stack

The Global Stack holds Prolog structures, lists, strings and long numbers. So the user's selection of data structures is largely responsible for the growth of this stack (cf. 5.4). In coroutining mode, delayed goals also consume space on the Global Stack. It also stores source variable names for terms which were read in with the flag variable_names being on. When this feature is not needed, it should be turned off so that space on the global stack is saved.

The global stack grows while a program creates data structures. It is popped only on failure. ECLiPSe therefore provides a garbage collector for the Global Stack which is called when a certain amount of new space has been consumed. See section 19.2 for how this process can be controlled. Note again that unnecessary nondeterminism reduces the amount of garbage that can be reclaimed and should therefore be avoided.

19.1.5  The Trail Stack

The Trail Stack is used to record information that is needed on backtracking. It is therefore closely related to the Control Stack. Ways to reduce Trail Stack consumption are The Trail Stack is popped on failure and is garbage collected together with the Global Stack.

Up Next