1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-28 16:21:07 -08:00
emacs/mps/manual/html/mmref/alloc.html
Gareth Rees 28419106ca Build html version of the manual in manual/html.
Check in HTML version of the manual (writable on client) so that it will display automatically on the Ravenbrook server and so that we can easily include it in product releases.

Copied from Perforce
 Change: 180338
 ServerID: perforce.ravenbrook.com
2012-11-05 17:18:50 +00:00

250 lines
No EOL
14 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>2. Allocation techniques &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Introduction to memory management" href="index.html" />
<link rel="next" title="3. Recycling techniques" href="recycle.html" />
<link rel="prev" title="1. Overview" href="begin.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="recycle.html" title="3. Recycling techniques"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="begin.html" title="1. Overview"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Introduction to memory management</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="allocation-techniques">
<span id="mmref-alloc"></span><h1>2. Allocation techniques<a class="headerlink" href="#allocation-techniques" title="Permalink to this headline"></a></h1>
<p>Memory allocation is the process of assigning blocks of memory on
request. Typically the <a class="reference internal" href="../glossary/a.html#term-allocator"><em class="xref std std-term">allocator</em></a> receives memory from the
operating system in a small number of large blocks that it must divide
up to satisfy the requests for smaller blocks. It must also make any
returned blocks available for reuse. There are many common ways to
perform this, with different strengths and weaknesses. A few are
described briefly below.</p>
<ul class="simple">
<li><a class="reference internal" href="#mmref-alloc-first-fit"><em>First fit</em></a></li>
<li><a class="reference internal" href="#mmref-alloc-buddy"><em>Buddy system</em></a></li>
<li><a class="reference internal" href="#mmref-alloc-suballocator"><em>Suballocators</em></a></li>
</ul>
<p>These techniques can often be used in combination.</p>
<div class="section" id="first-fit">
<span id="mmref-alloc-first-fit"></span><h2>2.1. First fit<a class="headerlink" href="#first-fit" title="Permalink to this headline"></a></h2>
<p>In the <a class="reference internal" href="../glossary/f.html#term-first-fit"><em class="xref std std-term">first fit</em></a> algorithm, the allocator keeps a list of free
blocks (known as the <a class="reference internal" href="../glossary/f.html#term-free-list"><em class="xref std std-term">free list</em></a>) and, on receiving a request
for memory, scans along the list for the first block that is large
enough to satisfy the request. If the chosen block is significantly
larger than that requested, then it is usually split, and the
remainder added to the list as another free block.</p>
<p>The first fit algorithm performs reasonably well, as it ensures that
allocations are quick. When recycling free blocks, there is a choice
as to where to add the blocks to the free list&#8212;effectively in what
order the free list is kept:</p>
<p><strong>Memory location (address)</strong></p>
<blockquote>
<div>This is not fast for allocation or recycling, but supports
efficient merging of adjacent free blocks (known as
<a class="reference internal" href="../glossary/c.html#term-coalesce"><em class="xref std std-term">coalescence</em></a>). According to <a class="reference internal" href="bib.html#wil95"><em>Wilson et al.
(1995)</em></a>, this ordering reduces <a class="reference internal" href="../glossary/f.html#term-fragmentation"><em class="xref std std-term">fragmentation</em></a>. It
can also improve <a class="reference internal" href="../glossary/l.html#term-locality-of-reference"><em class="xref std std-term">locality of reference</em></a>.</div></blockquote>
<p><strong>Increasing size</strong></p>
<blockquote>
<div>This is equivalent to the <a class="reference internal" href="../glossary/b.html#term-best-fit"><em class="xref std std-term">best fit</em></a> algorithm, in that the
free block with the &#8220;tightest fit&#8221; is always chosen. The fit is
usually sufficiently tight that the remainder of the block is
unusably small.</div></blockquote>
<p><strong>Decreasing size</strong></p>
<blockquote>
<div>This is equivalent to the <a class="reference internal" href="../glossary/w.html#term-worst-fit"><em class="xref std std-term">worst fit</em></a> algorithm. The first
block on the free list will always be large enough, if a large
enough block is available. This approach encourages
<a class="reference internal" href="../glossary/e.html#term-external-fragmentation"><em class="xref std std-term">external fragmentation</em></a>, but allocation is very fast.</div></blockquote>
<p><strong>Increasing time since last use</strong></p>
<blockquote>
<div>This is very fast at adding new free blocks, because they are
added to the beginning of the list. It encourages good
<a class="reference internal" href="../glossary/l.html#term-locality-of-reference"><em class="xref std std-term">locality of reference</em></a> (where blocks used together are not
spread throughout memory), but can lead to bad external
fragmentation.</div></blockquote>
<p>A variation of first fit, known as <a class="reference internal" href="../glossary/n.html#term-next-fit"><em class="xref std std-term">next fit</em></a>, continues each
search for a suitable block where the previous one left off, by using
a roving pointer into the free block chain. This is not usually
combined with increasing or decreasing size ordering because it would
eliminate their advantages.</p>
</div>
<div class="section" id="buddy-system">
<span id="mmref-alloc-buddy"></span><h2>2.2. Buddy system<a class="headerlink" href="#buddy-system" title="Permalink to this headline"></a></h2>
<p>In a <a class="reference internal" href="../glossary/b.html#term-buddy-system"><em class="xref std std-term">buddy system</em></a>, the allocator will only allocate blocks of
certain sizes, and has many free lists, one for each permitted size.
The permitted sizes are usually either powers of two, or form a
Fibonacci sequence (see below for example), such that any block except
the smallest can be divided into two smaller blocks of permitted
sizes.</p>
<p>When the allocator receives a request for memory, it rounds the
requested size up to a permitted size, and returns the first block
from that size&#8217;s free list. If the free list for that size is empty,
the allocator splits a block from a larger size and returns one of the
pieces, adding the other to the appropriate free list.</p>
<p>When blocks are recycled, there may be some attempt to merge adjacent
blocks into ones of a larger permitted size (<a class="reference internal" href="../glossary/c.html#term-coalesce"><em class="xref std std-term">coalescence</em></a>). To make this easier, the free lists may be stored in
order of address. The main advantage of the buddy system is that
coalescence is cheap because the &#8220;buddy&#8221; of any free block can be
calculated from its address.</p>
<div class="figure align-center">
<img alt="Diagram: A binary buddy heap before allocation." src="../_images/buddy1.svg" /><p class="caption">A binary buddy heap before allocation</p>
</div>
<div class="figure align-center">
<img alt="Diagram: A binary buddy heap after allocating a 8&nbsp;kB block." src="../_images/buddy2.svg" /><p class="caption">A binary buddy heap after allocating a 8&nbsp;kB block.</p>
</div>
<div class="figure align-center">
<img alt="Diagram: A binary buddy heap after allocating a 10&nbsp;kB block; note the 6&nbsp;kB wasted because of rounding up." src="../_images/buddy3.svg" /><p class="caption">A binary buddy heap after allocating a 10&nbsp;kB block; note the 6&nbsp;kB wasted because of rounding up.</p>
</div>
<p>For example, an allocator in a binary buddy system might have sizes of
16, 32, 64, …, 64&nbsp;kB. It might start off with a single block of 64&nbsp;kB.
If the application requests a block of 8&nbsp;kB, the allocator would check
its 8&nbsp;kB free list and find no free blocks of that size. It would then
split the 64&nbsp;kB block into two block of 32&nbsp;kB, split one of them into
two blocks of 16&nbsp;kB, and split one of them into two blocks of 8&nbsp;kB.
The allocator would then return one of the 8&nbsp;kB blocks to the
application and keep the remaining three blocks of 8&nbsp;kB, 16&nbsp;kB, and 32
kB on the appropriate free lists. If the application then requested a
block of 10&nbsp;kB, the allocator would round this request up to 16&nbsp;kB,
and return the 16&nbsp;kB block from its free list, wasting 6&nbsp;kB in the
process.</p>
<p>A Fibonacci buddy system might use block sizes 16, 32, 48, 80, 128,
208, … bytes, such that each size is the sum of the two preceding
sizes. When splitting a block from one free list, the two parts get
added to the two preceding free lists.</p>
<p>A buddy system can work very well or very badly, depending on how the
chosen sizes interact with typical requests for memory and what the
pattern of returned blocks is. The rounding typically leads to a
significant amount of wasted memory, which is called <a class="reference internal" href="../glossary/i.html#term-internal-fragmentation"><em class="xref std std-term">internal
fragmentation</em></a>. This can be reduced by making the permitted block
sizes closer together.</p>
</div>
<div class="section" id="suballocators">
<span id="mmref-alloc-suballocator"></span><h2>2.3. Suballocators<a class="headerlink" href="#suballocators" title="Permalink to this headline"></a></h2>
<p>There are many examples of application programs that include
additional memory management code called a <a class="reference internal" href="../glossary/s.html#term-suballocator"><em class="xref std std-term">suballocator</em></a>. A
suballocator obtains large blocks of memory from the system memory
manager and allocates the memory to the application in smaller pieces.
Suballocators are usually written for one of the following reasons:</p>
<ul class="simple">
<li>To avoid general inefficiency in the system memory manager;</li>
<li>To take advantage of special knowledge of the application&#8217;s memory
requirements that cannot be expressed to the system memory manager;</li>
<li>To provide memory management services that the system memory manager
does not supply.</li>
</ul>
<p>In general, suballocators are less efficient than having a single
memory manager that is well-written and has a flexible interface. It
is also harder to avoid memory management bugs if the memory manager
is composed of several layers, and if each application has its own
variation of suballocator.</p>
<p>Many applications have one or two sizes of block that form the vast
majority of their allocations. One of the most common uses of a
suballocator is to supply the application with objects of one size.
This greatly reduces the problem of <a class="reference internal" href="../glossary/e.html#term-external-fragmentation"><em class="xref std std-term">external fragmentation</em></a>.
Such a suballocator can have a very simple allocation policy.</p>
<p>There are dangers involved in making use of special knowledge of the
application&#8217;s memory requirements. If those requirements change, then
the performance of the suballocator is likely to be much worse than
that of a general allocator. It is often better to have a memory
manager that can respond dynamically to changing requirements.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">2. Allocation techniques</a><ul>
<li><a class="reference internal" href="#first-fit">2.1. First fit</a></li>
<li><a class="reference internal" href="#buddy-system">2.2. Buddy system</a></li>
<li><a class="reference internal" href="#suballocators">2.3. Suballocators</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="begin.html"
title="previous chapter">1. Overview</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="recycle.html"
title="next chapter">3. Recycling techniques</a></p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="recycle.html" title="3. Recycling techniques"
>next</a> |</li>
<li class="right" >
<a href="begin.html" title="1. Overview"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Introduction to memory management</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2012, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>