| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following sections only apply to the ECL original garbage collector.
If ECL is not compiled with --disable-boehm, then an alternative,
less restrictive garbage collector is installed, with the disadvantage
that many of the following functions #'room, si:*gc-verbose*,
... do no longer work.
4.1 Implementation Types 4.2 Heap and Relocatable Areas 4.3 The Garbage Collector 4.4 Allocation Functions 4.5 Storage Information
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each ECL object belongs to one of the 22 implementation types. The
implementation types are shown in Table 4-1 with the corresponding Common-Lisp
data types. In the table, the compiled functions are divided into three
implementation types; cfun is the type of compiled functions without
environment, cclosure is the type of compiled functions with environment
(i.e., the type of compiled closures) and gfun is the type of compiled
generic functions of CLOS.
cons | cons |
| fixnum | |
bignum | bignum |
ratio | ratio |
short-float | short-float |
long-float | long-float (= double-float = single-float) |
complex | complex |
character | character |
symbol | symbol |
package | package |
hash-table | hash-table |
array | (and array (not vector)) |
vector | (and vector (not string) (not bit-vector)) |
string | string |
bit-vector | bit-vector |
structure | structure |
stream | stream |
random-state | random-state |
readtable | readtable |
cfun | compiled-function without environment |
cclosure | compiled-function with environment |
gfun | none (CLOS generic-function) |
instance | none (CLOS instance) |
thread | none (thread) |
Each object is represented by a cell allocated in the heap area of the interpreter. The size of the cell is determined by the implementation type of the object.
The implementation types are classified according to the size of the cells for the objects of the type, as shown in Table 4-2. The size of the cells in the same type class is the same.
| 1 | CONS BIGNUM RATIO COMPLEX STRUCTURE |
| 2 | SHORT-FLOAT RANDOM-STATE READTABLE |
| 3 | LONG-FLOAT CFUN CCLOSURE |
| 4 | SYMBOL |
| 5 | PACKAGE |
| 6 | ARRAY HASH-TABLE VECTOR BIT-VECTOR STREAM |
| 7 | STRING |
| 8 | PATHNAME |
For objects of the (implementation) types readtable, symbol,
package, array, hash-table, vector,
bit-vector, stream, cclosure, string, cfun,
and structure (or instance), the cell is simply a header of the
object. The body of the object is allocated separately from the cell and is
managed in a different manner. The memory space occupied by the body of such
an object is called a block. A block is either contiguous or
relocatable depending on the area in which it is allocated. The
difference between the two areas will be explained below. Table 4-3 lists
these types, along with the contents of the body and the kind of the block.
readtable | read table | contiguous |
symbol | symbol name | relocatable |
package | hash table | contiguous |
array | array body | relocatable or contiguous |
hash-table | hash table | relocatable |
vector | vector body | relocatable or contiguous |
bit-vector | bit-vector body | relocatable or contiguous |
stream | I/O buffer | contiguous |
cclosure | code | contiguous |
string | string body | relocatable or contiguous |
cfun | code | contiguous |
structure | structure body | relocatable |
instance | instance slots | relocatable |
thread | thread data | contiguous |
Usually, the body of an array, a vector, a bit-vector, or a string is allocated
as a relocatable block. In ECL, the function make-array takes an
extra keyword argument :static@c. If the :static
with a non-()
contiguous block.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The memory space of ECL is divided into two parts: the heap area and the relocatable area. Both areas occupy a contiguous space in the memory.
Cells of ECL objects are allocated in the heap. ECL divides the heap into pages (1 page = 2048 bytes), and each page consists of cells in the same type class (see Table 4-2). Cells in different type classes are allocated in different pages. Some blocks are also allocated in the heap: They are called contiguous blocks. The pages for contiguous blocks contain only contiguous blocks. Thus each page in the heap is either a page for cells in a particular type class, or a page for contiguous blocks. Blocks not in the heap are called relocatable blocks and are allocated in the relocatable area.
The user may specify the maximum number of pages that can be allocated for each
type class by calling the ECL specific function allocate. There is
also a limit on the number of pages for contiguous blocks; the limit can be
altered by calling the ECL specific function
allocate-contiguous-pages size of the relocatable area is specified by
the ECL specific function allocate-relocatable-pages. See Section
4.4 for these functions.
In some installations of ECL, the total amount of memory that ECL can use is limited. In such cases, the entire memory may become exhausted before the maximum number of pages for each type class, for contiguous blocks, or for the relocatable area have been allocated.
The heap lies in a part of memory with lower address than the relocatable area and there is a "hole" between the two areas (see Figure 4-1). On request for a new page of heap, the page with the lowest address in the hole is used. When the hole is exhausted, the relocatable area is shifted toward the higher address space and a new hole of an appropriate size is created between the two areas.
Lower address Higher address +--------------+-------------------+---------------+ + HEAP | HOLE | RELOCATABLE | +--------------+-------------------+---------------+ |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ECL uses a conservative garbage collection technique for collecting the C stack and a type accurate technique for areas containing Lisp objects. Scanning conservatively the C stack, looking for potential pointers to Lisp objects, ensures that no live Lisp objects get collected, even if they are passed to external procedures in C or some other language. This approach greatly simplifies integration of Lisp and C code, since it is not necessary to protect Lisp object form collection when a foreign function is invoked.
The garbage collector of ECL has three levels according to what it collects:
In levels 2 and 3, the relocatable area is shifted to the higher address space to reserve an appropriate number of pages in the hole.
For each type class, ECL keeps a free list of unused cells, and when the free list is exhausted, a new page is allocated, or the garbage collector is invoked, depending on whether the maximum number of pages for that class have been allocated or not.
The garbage collector does not compact the heap. That is, cells and contiguous blocks are never moved to another place. Moreover, once a page is allocated for a particular type class or for contiguous blocks, that page will never be freed for other classes, even if the entire page becomes garbage.
On the other hand, the relocatable area is compacted during level 2 and level 3 of garbage collection. A relocatable block is really relocatable.
The garbage collector is automatically invoked in one of the following situations. The number in the parentheses indicates the level of garbage collection that is performed.
The garbage collector is also invoked by the following ECL specific function.
sys:*gc-verbose* is non-()@c, then it print messages at the start and
end of each garbage collection.
sys:*gc-verbose* is
()@c, gc fore goes printing any messages. The default value is T.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If the pages for a particular type class are exhausted after the maximum number
of pages for that class have been allocated, and if there remain no free cells
(actually, if there remain very few cells), ECL behaves as directed by the
argument that was initially passed to the ECL specific function (si::ignore-maximum-pages). If the
value is ()@c, then ECL signals a correctable error and enters the break loop.
The user can reset the maximum number by calling allocate and then
continue the execution of the program by typing :r@c.
Example:
>(make-list 100000)
Correctable error: The storage for CONS is exhausted.
Currently, 531 pages are allocated.
Use ALLOCATE to expand the space.
Signalled by MAKE-LIST.
Broken at FUNCALL.
>>(ALLOCATE 'CONS 1000)
t
>>:r
(nil nil nil nil nil nil nil nil nil nil ............
|
(si::ignore-maximum-pages) is non-()@c, then ECL automatically
increments the maximum number of pages for the class by 50 percent. The
initial value of (si::ignore-maximum-pages) is T@c.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
room prints the storage information. The argument
x is simply ignored and
the output of room is always in the same
format. room prints the following information:
The number of times the garbage collector has been called is not shown, if the number is zero.
In the following example, the maximum of 531 pages have already been
allocated for the type class to which cons belongs, but only 16.9 percent of
the cells are actually used. The garbage collector was once invoked to collect
cells in this type class.
> (room)
200/200 48.4% CONS BIGNUM RATIO COMPLEX STRUCTURE
1/5 7.4% SHORT-FLOAT RANDOM-STATE READTABLE
10/34 99.3% LONG-FLOAT CFUN CCLOSURE
47/64 71.9% SYMBOL
1/1 8.9% PACKAGE
2/69 81.8% ARRAY HASH-TABLE VECTOR BIT-VECTOR STREAM
16/40 95.9% STRING
1/1 6.8% PATHNAME
0/271 contiguous (1 blocks)
127 hole
40 3.4% relocatable
278 pages for cells
445 total pages
14709 pages available
1230 pages in heap but not gc'd + pages needed for gc marking
16384 maximum pages
|
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |