mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-30 00:51:50 -08:00
262 lines
No EOL
15 KiB
HTML
262 lines
No EOL
15 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 — 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> »</li>
|
|
<li><a href="index.html" accesskey="U">Introduction to memory management</a> »</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—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 “tightest fit” 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’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 “buddy” 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 kB block." src="../_images/buddy2.svg" /><p class="caption">A binary buddy heap after allocating a 8 kB block.</p>
|
|
</div>
|
|
<div class="figure align-center">
|
|
<img alt="Diagram: A binary buddy heap after allocating a 10 kB block; note the 6 kB wasted because of rounding up." src="../_images/buddy3.svg" /><p class="caption">A binary buddy heap after allocating a 10 kB block; note the 6 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 kB. It might start off with a single block of 64 kB.
|
|
If the application requests a block of 8 kB, the allocator would check
|
|
its 8 kB free list and find no free blocks of that size. It would then
|
|
split the 64 kB block into two block of 32 kB, split one of them into
|
|
two blocks of 16 kB, and split one of them into two blocks of 8 kB.
|
|
The allocator would then return one of the 8 kB blocks to the
|
|
application and keep the remaining three blocks of 8 kB, 16 kB, and 32
|
|
kB on the appropriate free lists. If the application then requested a
|
|
block of 10 kB, the allocator would round this request up to 16 kB,
|
|
and return the 16 kB block from its free list, wasting 6 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’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’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>Downloads</h4>
|
|
|
|
<p class="topless">
|
|
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
|
|
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
|
|
</p>
|
|
|
|
<h4>Issues</h4>
|
|
|
|
<p class="topless">
|
|
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&view=status%3dopen&display=Job:Priority:Title&sort=Priority">Known issues</a><br>
|
|
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</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> »</li>
|
|
<li><a href="index.html" >Introduction to memory management</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |