470 lines
29 KiB
HTML
470 lines
29 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<!-- Created by GNU Texinfo 7.0.3, https://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<title>Memory Management (ECL Manual)</title>
|
||
|
|
||
|
<meta name="description" content="Memory Management (ECL Manual)">
|
||
|
<meta name="keywords" content="Memory Management (ECL Manual)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content="makeinfo">
|
||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
|
||
|
<link href="index.html" rel="start" title="Top">
|
||
|
<link href="Indexes.html" rel="index" title="Indexes">
|
||
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
||
|
<link href="Extensions.html" rel="up" title="Extensions">
|
||
|
<link href="Meta_002dObject-Protocol-_0028MOP_0029.html#Meta_002dObject-Protocol-_0028MOP_0029" rel="next" title="Meta-Object Protocol (MOP)">
|
||
|
<link href="Signals-and-Interrupts.html#Signals-and-Interrupts" rel="prev" title="Signals and Interrupts">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
/* colors */
|
||
|
|
||
|
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
span.r {font-family: initial; font-weight: normal; font-style: normal}
|
||
|
span:hover a.copiable-link {visibility: visible}
|
||
|
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
|
||
|
ul.mark-bullet {list-style-type: disc}
|
||
|
@media (prefers-color-scheme: dark) {
|
||
|
/* dark theme */
|
||
|
html { color: seashell;
|
||
|
background: #1A1A1A; }
|
||
|
body { background: #1A1A1A; }
|
||
|
th { border-bottom: 2px solid lightgray; }
|
||
|
h1, h2, h3, h4, h5 { background-image: linear-gradient(to left, #202020, #3A3A3A); }
|
||
|
code, var, code a { color: darkorange;
|
||
|
background: #2A2A2A; }
|
||
|
a { color: seashell; }
|
||
|
pre { background: #2A2A2A;
|
||
|
color: seashell;
|
||
|
/* mark longer code block with stripe on the left */
|
||
|
border-left: 5px solid darkorange;
|
||
|
padding-left: 10px; }
|
||
|
pre.screen { background: #2A2A2A;
|
||
|
border: 1px solid lightgray; }
|
||
|
pre.programlisting { background: #2A2A2A;
|
||
|
border-left: 1px solid lightgray;
|
||
|
border-top: 1px solid lightgray; }
|
||
|
/* we need a light background in order for the images to be readable */
|
||
|
img { background: white }
|
||
|
}
|
||
|
@media (prefers-color-scheme: light) {
|
||
|
/* light theme */
|
||
|
html { background: white }
|
||
|
body { background: white }
|
||
|
th { border-bottom: 2px solid gray; }
|
||
|
h1, h2, h3, h4, h5 { background: lightgray; }
|
||
|
code, var, code a { color: darkred;
|
||
|
background: whitesmoke; }
|
||
|
a { color: #000; }
|
||
|
pre { background: whitesmoke;
|
||
|
color: black;
|
||
|
/* mark longer code block with stripe on the left */
|
||
|
border-left: 5px solid darkred;
|
||
|
padding-left: 10px; }
|
||
|
pre.screen { background: #EEE;
|
||
|
border: 1px solid black; }
|
||
|
pre.programlisting { background: #EEEEEE;
|
||
|
border-left: 1px solid black;
|
||
|
border-top: 1px solid black; }
|
||
|
}
|
||
|
|
||
|
body {
|
||
|
margin: 1em 125px 0 10%;
|
||
|
line-height: 1.5em;
|
||
|
padding: 0 2em 1em 2em;
|
||
|
font: 13px Verdana,Arial, sans-serif
|
||
|
}
|
||
|
ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
|
||
|
p, code, td, dl, dt {
|
||
|
line-height: 1.5em;
|
||
|
}
|
||
|
table {
|
||
|
font: inherit;
|
||
|
border-collapse: collapse;
|
||
|
}
|
||
|
th, td {
|
||
|
vertical-align: top;
|
||
|
}
|
||
|
h1, h2, h3 { padding-left: 15px; }
|
||
|
h4, h5 { padding-left: 5px; }
|
||
|
code, pre {
|
||
|
font-size: 1em;
|
||
|
font-family: monospace;
|
||
|
}
|
||
|
var {
|
||
|
font-size: 1em;
|
||
|
}
|
||
|
/* links inside code appear the same as the code itself */
|
||
|
code a {
|
||
|
font-weight: normal;
|
||
|
text-decoration: none;
|
||
|
}
|
||
|
/* but get an underline when hovering */
|
||
|
code a:hover {
|
||
|
text-decoration: underline;
|
||
|
}
|
||
|
/* ordinary links appear in bold */
|
||
|
a { font-weight: bold; }
|
||
|
pre.verbatim {
|
||
|
margin: 0 0 0 0;
|
||
|
}
|
||
|
pre {
|
||
|
overflow: auto;
|
||
|
}
|
||
|
pre.screen {
|
||
|
font-weight: bold;
|
||
|
padding: 0.5em;
|
||
|
}
|
||
|
pre.programlisting {
|
||
|
padding: 0.5em;
|
||
|
}
|
||
|
div p { padding: 0 2em }
|
||
|
li p { padding: 0; margin: 0 }
|
||
|
hr { display: none; }
|
||
|
div.funcsynopsis p {
|
||
|
text-indent: -2em;
|
||
|
}
|
||
|
div.variablelist {
|
||
|
padding: 0 2em;
|
||
|
}
|
||
|
.type, .funcsynopsis, .symbol {
|
||
|
font-family: monospace;
|
||
|
}
|
||
|
.type, .symbol, .replaceable {
|
||
|
white-space: nowrap;
|
||
|
}
|
||
|
|
||
|
-->
|
||
|
</style>
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<div class="section-level-extent" id="Memory-Management">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Meta_002dObject-Protocol-_0028MOP_0029.html#Meta_002dObject-Protocol-_0028MOP_0029" accesskey="n" rel="next">Meta-Object Protocol (MOP)</a>, Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="p" rel="prev">Signals and Interrupts</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h3 class="section" id="Memory-Management-1">3.6 Memory Management</h3>
|
||
|
|
||
|
|
||
|
<ul class="mini-toc">
|
||
|
<li><a href="Memory-Management.html#Memory-Management-Introduction" accesskey="1">Introduction</a></li>
|
||
|
<li><a href="Memory-Management.html#Boehm_002dWeiser-garbage-collector" accesskey="2">Boehm-Weiser garbage collector</a></li>
|
||
|
<li><a href="Memory-Management.html#Memory-limits" accesskey="3">Memory limits</a></li>
|
||
|
<li><a href="Memory-Management.html#Memory-conditions" accesskey="4">Memory conditions</a></li>
|
||
|
<li><a href="Memory-Management.html#Finalization" accesskey="5">Finalization</a></li>
|
||
|
<li><a href="Memory-Management.html#Memory-Management-Reference" accesskey="6">Memory Management Reference</a></li>
|
||
|
</ul>
|
||
|
<hr>
|
||
|
<div class="subsection-level-extent" id="Memory-Management-Introduction">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Memory-Management.html#Boehm_002dWeiser-garbage-collector" accesskey="n" rel="next">Boehm-Weiser garbage collector</a>, Up: <a href="Memory-Management.html#Memory-Management" accesskey="u" rel="up">Memory Management</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Introduction-2">3.6.1 Introduction</h4>
|
||
|
<a class="index-entry-id" id="index-Memory-management"></a>
|
||
|
<p>ECL relies on the Boehm-Weiser garbage collector for handling memory, creating and destroying objects, and handling finalization of objects that are no longer reachable. The use of a garbage collector, and in particular the use of a portable one, imposes certain restrictions that may appear odd for C/C++ programmers.
|
||
|
</p>
|
||
|
<p>In this section we will discuss garbage collection, how ECL configures and uses the memory management library, what users may expect, how to handle the memory and how to control the process by which objects are deleted.
|
||
|
</p>
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="Boehm_002dWeiser-garbage-collector">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Memory-Management.html#Memory-limits" accesskey="n" rel="next">Memory limits</a>, Previous: <a href="Memory-Management.html#Memory-Management-Introduction" accesskey="p" rel="prev">Introduction</a>, Up: <a href="Memory-Management.html#Memory-Management" accesskey="u" rel="up">Memory Management</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Boehm_002dWeiser-garbage-collector-1">3.6.2 Boehm-Weiser garbage collector</h4>
|
||
|
<p>First of all, the garbage collector must be able to determine which objects are alive and which are not. In other words, the collector must able to find all references to an object. One possibility would be to know where all variables of a program reside, and where is the stack of the program and its size, and parse all data there, discriminating references to lisp objects. To do this precisely one would need a very precise control of the data and stack segments, as well as how objects are laid out by the C compiler. This is beyond ECL’s scope and wishes and it can make coexistence with other libraries (C++, Fortran, etc) difficult.
|
||
|
</p>
|
||
|
<p>The Boehm-Weiser garbage collector, on the other hand, is a conservative garbage collector. When scanning memory looking for references to live data, it guesses, conservatively, whether a word is a pointer or not. In case of doubt it will consider it to be a pointer and add it to the list of live objects. This may cause certain objects to be retained longer than what an user might expect but, in our experience, this is the best of both worlds and ECL uses certain strategies to minimize the amount of misinterpreted data.
|
||
|
</p>
|
||
|
<p>More precisely, ECL uses the garbage collector with the following settings:
|
||
|
</p>
|
||
|
<ul class="itemize mark-bullet">
|
||
|
<li>The collector will not scan the data sectors. If you embed ECL in another program, or link libraries with ECL, you will have to notify ECL which variables point to lisp objects.
|
||
|
|
||
|
</li><li>The collector is configured to ignore pointers that point to the middle of allocated objects. This minimizes the risk of misinterpreting integers as pointers to live objects.
|
||
|
|
||
|
</li><li>It is possible to register finalizers that are invoked when an object is destroyed, but for that you should use ECL’s API and understand the restriction described later in <a class="ref" href="Memory-Management.html#Finalization">Finalization</a>.
|
||
|
</li></ul>
|
||
|
|
||
|
<p>Except for finalization, which is a questionable feature, the previous settings are not very relevant for Common Lisp programmers, but are crucial for people interested in embedding in or cooperating with other C, C++ or Fortran libraries. Care should be taken when manipulating directly the GC library to avoid interfering with ECL’s expectations.
|
||
|
</p>
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="Memory-limits">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Memory-Management.html#Memory-conditions" accesskey="n" rel="next">Memory conditions</a>, Previous: <a href="Memory-Management.html#Boehm_002dWeiser-garbage-collector" accesskey="p" rel="prev">Boehm-Weiser garbage collector</a>, Up: <a href="Memory-Management.html#Memory-Management" accesskey="u" rel="up">Memory Management</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Memory-limits-1">3.6.3 Memory limits</h4>
|
||
|
<p>Beginning with version 9.2.1, ECL operates a tighter control of the resources it uses. In particular, it features explicit limits in the four stacks and in the amount of live data. These limits are optional, can be changed at run time, but they allow users to better control the evolution of a program, handling memory and stack overflow gracefully via the Common Lisp condition system.
|
||
|
</p>
|
||
|
<p>The customizable limits are listed in <a class="ref" href="Memory-Management.html#tab_003amem_002dlimits">Table 3.1</a>, but they need a careful description.
|
||
|
</p>
|
||
|
<a class="anchor" id="ext_003aheap_002dsize"></a><a class="index-entry-id" id="index-ext_003aheap_002dsize"></a>
|
||
|
<a class="anchor" id="ext_003ac_002dstack"></a><a class="index-entry-id" id="index-ext_003ac_002dstack"></a>
|
||
|
<a class="anchor" id="ext_003abinding_002dstack"></a><a class="index-entry-id" id="index-ext_003abinding_002dstack"></a>
|
||
|
<a class="anchor" id="ext_003aframe_002dstack"></a><a class="index-entry-id" id="index-ext_003aframe_002dstack"></a>
|
||
|
<a class="anchor" id="ext_003alisp_002dstack"></a><a class="index-entry-id" id="index-ext_003alisp_002dstack"></a>
|
||
|
<ul class="itemize mark-bullet">
|
||
|
<li><code class="code"><a class="ref" href="Memory-Management.html#ext_003aheap_002dsize">ext:heap-size</a></code> limits the total amount of memory which is available for lisp objects. This is the memory used when you create conses, arrays, structures, etc.
|
||
|
</li><li><code class="code"><a class="ref" href="Memory-Management.html#ext_003ac_002dstack">ext:c-stack</a></code> controls the size of the stack for compiled code, including ECL’s library itself. This limit is less stringent than the others. For instance, when code is compiled with low safety settings, checks for this stack limit are usually omitted, for performance reasons.
|
||
|
</li><li><code class="code"><a class="ref" href="Memory-Management.html#ext_003abinding_002dstack">ext:binding-stack</a></code> controls the number of nested bindings for special variables. The current value is usually safe enough, unless you have deep recursive functions that bind special variables, which is not really a good idea.
|
||
|
</li><li><code class="code"><a class="ref" href="Memory-Management.html#ext_003aframe_002dstack">ext:frame-stack</a></code> controls the number of nested blocks, tagbodys and other control structures. It affects both interpreted and compiled code, but quite often compiled code optimizes away these stack frames, saving memory and not being affected by this limit.
|
||
|
</li><li><code class="code"><a class="ref" href="Memory-Management.html#ext_003alisp_002dstack">ext:lisp-stack</a></code> controls the size of the interpreter stack. It only affects interpreted code.
|
||
|
</li></ul>
|
||
|
|
||
|
<p>If you look at <a class="ref" href="Memory-Management.html#tab_003amem_002dlimits">Table 3.1</a>, some of these limits may seem very stringent, but they exist to allow detecting and correcting both stack and memory overflow conditions. Larger values can be set systematically either in the <samp class="file">~/.eclrc</samp> initialization file, or using the command line options from the table.
|
||
|
</p>
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="Memory-conditions">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Memory-Management.html#Finalization" accesskey="n" rel="next">Finalization</a>, Previous: <a href="Memory-Management.html#Memory-limits" accesskey="p" rel="prev">Memory limits</a>, Up: <a href="Memory-Management.html#Memory-Management" accesskey="u" rel="up">Memory Management</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Memory-conditions-1">3.6.4 Memory conditions</h4>
|
||
|
<p>When ECL surpasses or approaches the memory limits it will signal a Common Lisp condition. There are two types of conditions, <code class="code"><a class="ref" href="Memory-Management.html#ext_003astack_002doverflow">ext:stack-overflow</a></code> and <code class="code"><a class="ref" href="Memory-Management.html#ext_003astorage_002dexhausted">ext:storage-exhausted</a></code>, for stack and heap overflows, respectively. Both errors are correctable, as the following session shows:
|
||
|
</p><div class="example lisp">
|
||
|
<pre class="lisp-preformatted">> (defun foo (x) (foo x))
|
||
|
|
||
|
FOO
|
||
|
> (foo 1)
|
||
|
C-STACK overflow at size 1654784. Stack can probably be resized.
|
||
|
Broken at SI:BYTECODES.Available restarts:
|
||
|
1. (CONTINUE) Extend stack size
|
||
|
Broken at FOO.
|
||
|
>> :r1
|
||
|
C-STACK overflow at size 2514944. Stack can probably be resized.
|
||
|
Broken at SI:BYTECODES.Available restarts:
|
||
|
1. (CONTINUE) Extend stack size
|
||
|
Broken at FOO.
|
||
|
>> :q
|
||
|
Top level.
|
||
|
</pre></div>
|
||
|
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="Finalization">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Memory-Management.html#Memory-Management-Reference" accesskey="n" rel="next">Memory Management Reference</a>, Previous: <a href="Memory-Management.html#Memory-conditions" accesskey="p" rel="prev">Memory conditions</a>, Up: <a href="Memory-Management.html#Memory-Management" accesskey="u" rel="up">Memory Management</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Finalization-1">3.6.5 Finalization</h4>
|
||
|
<p>As we all know, Common-Lisp relies on garbage collection for deleting unreachable objects. However, it makes no provision for the equivalent of a C++ Destructor function that should be called when the object is eliminated by the garbage collector. The equivalent of such methods in a garbage collected environment is normally called a <em class="dfn">finalizer</em>.
|
||
|
</p>
|
||
|
<p>ECL includes a simple implementation of finalizers which makes the following promises.
|
||
|
</p>
|
||
|
<ul class="itemize mark-bullet">
|
||
|
<li>The finalizer can be any lisp function, let it be compiled or interpreter.
|
||
|
</li><li>Finalizers are not invoked during garbage collection. Instead, if an unreachable object is found to have an associated finalizer, it is pushed into a list and <em class="emph">before the next garbage collection cycle</em>, the finalizer will be invoked.
|
||
|
</li><li>If the finalizer is invoked and it makes the object reachable, for instance, by assigning it to a variable, it will not be destroyed, but it will have no longer a finalizer associated to it.
|
||
|
</li><li>ECL will strive to call finalizers before the environment is closed and the program is finished, but this mechanism may fail when exiting in a non ordinary way.
|
||
|
</li></ul>
|
||
|
|
||
|
<p>The implementation is based on two functions, <code class="code"><a class="ref" href="Memory-Management.html#ext_003aset_002dfinalizer">ext:set-finalizer</a></code> and <code class="code"><a class="ref" href="Memory-Management.html#ext_003aget_002dfinalizer">ext:get-finalizer</a></code>, which allow setting and querying the finalizer functions for certain objects.
|
||
|
</p>
|
||
|
<hr>
|
||
|
</div>
|
||
|
<div class="subsection-level-extent" id="Memory-Management-Reference">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Previous: <a href="Memory-Management.html#Finalization" accesskey="p" rel="prev">Finalization</a>, Up: <a href="Memory-Management.html#Memory-Management" accesskey="u" rel="up">Memory Management</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<h4 class="subsection" id="Memory-Management-Reference-1">3.6.6 Memory Management Reference</h4>
|
||
|
|
||
|
<h4 class="subsubheading" id="Reference-6">Reference</h4>
|
||
|
|
||
|
<a class="anchor" id="ext_003astack_002doverflow"></a><a class="index-entry-id" id="index-ext_003astack_002doverflow"></a>
|
||
|
<dl class="first-deftp">
|
||
|
<dt class="deftp" id="index-ext_003astack_002doverflow-1"><span class="category-def">Condition: </span><span><strong class="def-name">ext:stack-overflow</strong><a class="copiable-link" href='Memory-Management.html#index-ext_003astack_002doverflow-1'> ¶</a></span></dt>
|
||
|
<dd>
|
||
|
<p>Stack overflow condition
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Class Precedence List</b>
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Memory-Management.html#ext_003astack_002doverflow">ext:stack-overflow</a></code>, <code class="code">storage-condition</code>, <code class="code">serious-condition</code>, <code class="code">condition</code>, <code class="code">t</code>
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Methods</b>
|
||
|
</p>
|
||
|
<a class="anchor" id="ext_003astack_002doverflow_002dsize"></a><a class="index-entry-id" id="index-ext_003astack_002doverflow_002dsize-1"></a>
|
||
|
<dl class="first-deffn first-defun-alias-first-deffn">
|
||
|
<dt class="deffn defun-alias-deffn" id="index-ext_003astack_002doverflow_002dsize"><span class="category-def">Function: </span><span><strong class="def-name">ext:stack-overflow-size</strong> <var class="def-var-arguments">condition</var><a class="copiable-link" href='Memory-Management.html#index-ext_003astack_002doverflow_002dsize'> ¶</a></span></dt>
|
||
|
<dd><dl class="table">
|
||
|
<dt><var class="var">returns</var></dt>
|
||
|
<dd><p>A non-negative integer.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
</dd></dl>
|
||
|
|
||
|
<a class="anchor" id="ext_003astack_002doverflow_002dtype"></a><a class="index-entry-id" id="index-ext_003astack_002doverflow_002dtype-1"></a>
|
||
|
<dl class="first-deffn first-defun-alias-first-deffn">
|
||
|
<dt class="deffn defun-alias-deffn" id="index-ext_003astack_002doverflow_002dtype"><span class="category-def">Function: </span><span><strong class="def-name">ext:stack-overflow-type</strong> <var class="def-var-arguments">condition</var><a class="copiable-link" href='Memory-Management.html#index-ext_003astack_002doverflow_002dtype'> ¶</a></span></dt>
|
||
|
<dd><dl class="table">
|
||
|
<dt><var class="var">returns</var></dt>
|
||
|
<dd><p>A symbol from <a class="ref" href="Memory-Management.html#tab_003amem_002dlimits">Table 3.1</a>, except <code class="code"><a class="ref" href="Memory-Management.html#ext_003aheap_002dsize">ext:heap-size</a></code>.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>This condition is signaled when one of the stack limits in <a class="ref" href="Memory-Management.html#tab_003amem_002dlimits">Table 3.1</a> are violated or dangerously approached. It can be handled by resetting the limits and continuing, or jumping to an outer control point.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ext_003astorage_002dexhausted"></a><a class="index-entry-id" id="index-ext_003astorage_002dexhausted"></a>
|
||
|
<dl class="first-deftp">
|
||
|
<dt class="deftp" id="index-ext_003astorage_002dexhausted-1"><span class="category-def">Condition: </span><span><strong class="def-name">ext:storage-exhausted</strong><a class="copiable-link" href='Memory-Management.html#index-ext_003astorage_002dexhausted-1'> ¶</a></span></dt>
|
||
|
<dd>
|
||
|
<p>Memory overflow condition
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Class Precedence List</b>
|
||
|
</p>
|
||
|
<p><code class="code"><a class="ref" href="Memory-Management.html#ext_003astorage_002dexhausted">ext:storage-exhausted</a></code>, <code class="code">storage-condition</code>, <code class="code">serious-condition</code>, <code class="code">condition</code>, <code class="code">t</code>
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>This condition is signaled when ECL exhausts the <code class="code"><a class="ref" href="Memory-Management.html#ext_003aheap_002dsize">ext:heap-size</a></code> limit from <a class="ref" href="Memory-Management.html#tab_003amem_002dlimits">Table 3.1</a>. In handling this condition ECL follows this logic:
|
||
|
</p><ul class="itemize mark-bullet">
|
||
|
<li>If the heap size limit was set to 0 (that is no limit), but there is some free space in the safety region ECL frees this space and issues a non-restartable error. The user may jump to an outer point or quit.
|
||
|
</li><li>If the heap size had a finite limit, ECL offers the user the chance to resize it, issuing a restartable condition. The user may at this point use <code class="code">(ext:set-limit 'ext:heap-size 0)</code> to remove the heap limit and avoid further messages, or use the <code class="code">(continue)</code> restart to let ECL enlarge the heap by some amount.
|
||
|
</li><li>Independently of the heap size limit, if ECL finds that there is no space to free or to grow, ECL simply quits. There will be no chance to do some cleanup because there is no way to allocate any additional data.
|
||
|
</li></ul>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ext_003aget_002dfinalizer"></a><a class="index-entry-id" id="index-ext_003aget_002dfinalizer-1"></a>
|
||
|
<dl class="first-deffn first-defun-alias-first-deffn">
|
||
|
<dt class="deffn defun-alias-deffn" id="index-ext_003aget_002dfinalizer"><span class="category-def">Function: </span><span><strong class="def-name">ext:get-finalizer</strong> <var class="def-var-arguments">object</var><a class="copiable-link" href='Memory-Management.html#index-ext_003aget_002dfinalizer'> ¶</a></span></dt>
|
||
|
<dd><dl class="table">
|
||
|
<dt><var class="var">object</var></dt>
|
||
|
<dd><p>Any lisp object.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>This function returns the finalizer associated to an object, or <code class="code">nil</code>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ext_003aget_002dlimit"></a><a class="index-entry-id" id="index-ext_003aget_002dlimit-1"></a>
|
||
|
<dl class="first-deffn first-defun-alias-first-deffn">
|
||
|
<dt class="deffn defun-alias-deffn" id="index-ext_003aget_002dlimit"><span class="category-def">Function: </span><span><strong class="def-name">ext:get-limit</strong> <var class="def-var-arguments">concept</var><a class="copiable-link" href='Memory-Management.html#index-ext_003aget_002dlimit'> ¶</a></span></dt>
|
||
|
<dd><dl class="table">
|
||
|
<dt><var class="var">concept</var></dt>
|
||
|
<dd><p>A symbol.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>Queries the different memory and stack limits that condition ECL’s behavior. The value to be queried is denoted by the symbol <var class="var">concept</var>, which should be one from the list: <a class="ref" href="Memory-Management.html#tab_003amem_002dlimits">Table 3.1</a>
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<a class="anchor" id="ext_003aset_002dfinalizer"></a><a class="index-entry-id" id="index-ext_003aset_002dfinalizer-1"></a>
|
||
|
<dl class="first-deffn first-defun-alias-first-deffn">
|
||
|
<dt class="deffn defun-alias-deffn" id="index-ext_003aset_002dfinalizer"><span class="category-def">Function: </span><span><strong class="def-name">ext:set-finalizer</strong> <var class="def-var-arguments">object function</var><a class="copiable-link" href='Memory-Management.html#index-ext_003aset_002dfinalizer'> ¶</a></span></dt>
|
||
|
<dd><p>Associate a finalizer to an object.
|
||
|
</p><dl class="table">
|
||
|
<dt><var class="var">object</var></dt>
|
||
|
<dd><p>Any lisp object.
|
||
|
</p></dd>
|
||
|
<dt><var class="var">function</var></dt>
|
||
|
<dd><p>A function or closure that takes one argument or <code class="code">nil</code>.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
|
||
|
|
||
|
<p><b class="b">Description</b>
|
||
|
</p>
|
||
|
<p>If <var class="var">function</var> is <code class="code">nil</code>, no finalizer is associated to the object. Otherwise <var class="var">function</var> must be a function or a closure of one argument, which will be invoked before the object is destroyed.
|
||
|
</p>
|
||
|
|
||
|
<p><b class="b">Example</b>
|
||
|
</p>
|
||
|
<p>Close a file associated to an object.
|
||
|
</p>
|
||
|
<div class="example lisp">
|
||
|
<pre class="lisp-preformatted">(defclass my-class () ((file :initarg :file :initform nil)))
|
||
|
|
||
|
(defun finalize-my-class (x)
|
||
|
(let ((s (slot-value x 'file)))
|
||
|
(when s (format t "~%;;; Closing" s) (close s))))
|
||
|
|
||
|
(defmethod initialize-instance :around ((my-instance my-class) &rest args)
|
||
|
(ext:set-finalizer my-instance #'finalize-my-class)
|
||
|
(call-next-method))
|
||
|
|
||
|
(progn
|
||
|
(make-instance 'my-class :file (open "~/.ecl.old" :direction :input))
|
||
|
nil)
|
||
|
|
||
|
(si::gc t)
|
||
|
(si::gc t)
|
||
|
|
||
|
;; Closing
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<a class="anchor" id="ext_003aset_002dlimit"></a><a class="index-entry-id" id="index-ext_003aset_002dlimit-1"></a>
|
||
|
<dl class="first-deffn first-defun-alias-first-deffn">
|
||
|
<dt class="deffn defun-alias-deffn" id="index-ext_003aset_002dlimit"><span class="category-def">Function: </span><span><strong class="def-name">ext:set-limit</strong> <var class="def-var-arguments">concept value</var><a class="copiable-link" href='Memory-Management.html#index-ext_003aset_002dlimit'> ¶</a></span></dt>
|
||
|
<dd><p>Set a memory or stack limit.
|
||
|
</p><dl class="table">
|
||
|
<dt><var class="var">concept</var></dt>
|
||
|
<dd><p>A symbol.
|
||
|
</p></dd>
|
||
|
<dt><var class="var">value</var></dt>
|
||
|
<dd><p>A positive integer.
|
||
|
</p></dd>
|
||
|
</dl>
|
||
|
<p>Changes the different memory and stack limits that condition ECL’s behavior. The value to be changed is denoted by the symbol <var class="var">concept</var>, while the <var class="var">value</var> is the new maximum size. The valid symbols and units are listed in <a class="ref" href="Memory-Management.html#tab_003amem_002dlimits">Table 3.1</a>.
|
||
|
</p>
|
||
|
<p>Note that the limit has to be positive, but it may be smaller than the previous value of the limit. However, if the supplied value is smaller than what ECL is using at the moment, the new value will be silently ignored.
|
||
|
</p>
|
||
|
<div class="float" id="tab_003amem_002dlimits">
|
||
|
|
||
|
<table class="multitable">
|
||
|
<thead><tr><th width="25%">Concept</th><th width="25%">Units</th><th width="25%">Default</th><th width="25%">Command line</th></tr></thead>
|
||
|
<tbody><tr><td width="25%">ext:frame-stack</td><td width="25%">Nested frames</td><td width="25%">2048</td><td width="25%"><code class="code">--frame-stack</code></td></tr>
|
||
|
<tr><td width="25%">ext:binding-stack</td><td width="25%">Bindings</td><td width="25%">8192</td><td width="25%"></td></tr>
|
||
|
<tr><td width="25%">ext:c-stack</td><td width="25%">Bytes</td><td width="25%">128 kilobytes</td><td width="25%"><code class="code">--c-stack</code></td></tr>
|
||
|
<tr><td width="25%">ext:heap-size</td><td width="25%">Bytes</td><td width="25%">256 megabytes</td><td width="25%"><code class="code">--heap-size</code></td></tr>
|
||
|
<tr><td width="25%">ext:lisp-stack</td><td width="25%">Bytes</td><td width="25%">32 kilobyes</td><td width="25%"><code class="code">--lisp-stack</code></td></tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<div class="caption"><p><strong class="strong">Table 3.1: </strong>Customizable memory limits</p></div></div>
|
||
|
</dd></dl>
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Next: <a href="Meta_002dObject-Protocol-_0028MOP_0029.html#Meta_002dObject-Protocol-_0028MOP_0029" accesskey="n" rel="next">Meta-Object Protocol (MOP)</a>, Previous: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="p" rel="prev">Signals and Interrupts</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|