<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Page_Frame_Allocation</id>
	<title>Page Frame Allocation - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Page_Frame_Allocation"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;action=history"/>
	<updated>2026-04-07T10:30:25Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=1134&amp;oldid=prev</id>
		<title>2022年4月5日 (二) 02:39 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=1134&amp;oldid=prev"/>
		<updated>2022-04-05T02:39:01Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2022年4月5日 (二) 02:39的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;（译者注：本文讨论了两个层次的页面帧分配算法：一个是物理内存拆分分配，一个是虚拟内存拆分分配。这里不仅要考虑速度还要考虑内存利用率等多方面问题，但是这里写的很简略，只是一个索引，还是得读其它资料才能自制一套出来。）&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;（译者注：页面帧分配器（Allocators）算法主要负责将完整连续内存拆分为大小合适的帧（Frame）供不同任务使用。这里不仅要考虑速度还要考虑内存利用率等多方面问题，但是这里写的很简略，只是一个索引，还是得读其它资料才能自制一套出来。）&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 物理内存分配器 ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 物理内存分配器 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l19&quot;&gt;第19行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第19行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Sized Portion 方案===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Sized Portion 方案===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;你将每个区域 (例如16kb) 分成(例如)1个8kb和2个4kb的块。 然后你按需分发每一块。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;通过这样做，你可以找到更接近精确尺寸的适合。 &lt;/del&gt;这意味着更少的浪费。 比如说你有32kb的区域&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;你将每个区域 (例如16kb) 分成(例如)1个8kb和2个4kb的块。 然后你按需分发每一块。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;通过这样做，你可以找到更精确的大小。 &lt;/ins&gt;这意味着更少的浪费。 比如说你有32kb的区域&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Image:Sized Portion Scheme.png]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Image:Sized Portion Scheme.png]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l36&quot;&gt;第36行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第36行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map（每位代表32K页面）&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map（每位代表32K页面）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;包含N个页面的一个Buddy大小大约是表示同一区域的Bitmap大小的两倍，但是它可以更快地定位页面集合。（译者注：如上表如果仅Bitmap只需要5字节-40位，而增加几个Buddy后，一共有40+20+10+5=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;75位 &lt;/del&gt;上图显示了一个4-buddy，其空闲页面/块表示为符号.（点号），已用页面/块表示为符号#。 当一个块包含至少一个已用子块时，它本身被标记为#&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;已用（译者注：表示此块作为整体已不可再使用），而属于较大块的子块在图中也被标记为x。（译者注：x应该是表示是残存的部分，也是未使用的，但是标记x是用理解以后期的内存合并拆分处理） &lt;/del&gt;假设我们要在这个Buddy上分配一个12k的region，我们将查找可用的16K块的位图 （也就是#12页，和#36页。译者注：因为只有在16K的大小能才能放入12K，所以只需要看buddy[2]的位映射情况）。 然后将buddy[2]-&amp;gt;bit[4]&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;设置为‘已使用’。（译者注：budyy&lt;/del&gt;[2]的第4位映射了#12页开头的16k内存，） 现在我们只想要4个页面中的3个，所以剩余的页面返回到适当的Buddy位映射中 (也就是#12开始只还剩了一个页的映射)。 由此产生的整体Buddy是（译者注：注意12往下的几层Buddy的状态变化）：&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;包含N个页面的一个Buddy大小大约是表示同一区域的Bitmap大小的两倍，但是它可以更快地定位页面集合。（译者注：如上表如果仅Bitmap只需要5字节-40位，而增加几个Buddy后，一共有40+20+10+5=&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;75位） &lt;/ins&gt;上图显示了一个4-buddy，其空闲页面/块表示为符号.（点号），已用页面/块表示为符号#。 当一个块包含至少一个已用子块时，它本身被标记为#&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;已用（译者注：表示此块作为整体已不可再使用），而属于较大块的子块在图中也被标记为x。（译者注：x应该是表示是残存的部分，也是未使用的，但是标记x应该是用于以后期的内存合并拆分处理） &lt;/ins&gt;假设我们要在这个Buddy上分配一个12k的region，我们将查找可用的16K块的位图 （也就是#12页，和#36页。译者注：因为只有在16K的大小能才能放入12K，所以只需要看buddy[2]的位映射情况）。 然后将buddy[2]-&amp;gt;bit[4]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;设置为‘已使用’。（译者注：buddy&lt;/ins&gt;[2]的第4位映射了#12页开头的16k内存，） 现在我们只想要4个页面中的3个，所以剩余的页面返回到适当的Buddy位映射中 (也就是#12开始只还剩了一个页的映射)。 由此产生的整体Buddy是（译者注：注意12往下的几层Buddy的状态变化）：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                   0   4   8   12  16  20  24  28  32  36&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                   0   4   8   12  16  20  24  28  32  36&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l54&quot;&gt;第54行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第54行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 混合方案 #2 ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 混合方案 #2 ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;也可以不是只跟踪代表页的位，或者只跟踪 [[stack|栈]]上的页码，而是使用一个大的结构数组来表示内存。 在这些页面框架结构中，存储指向下一页的单个链接 (指针大小) 和指示其状态的8-16位信息块。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;还包括虚拟页指针和页码所属的TCB。 &lt;/del&gt;保留指向每种类型页面的指针，指向列表的开始和结尾。 通过这种方式，你可以轻松地显示有关其内容的信息，每种类型的可用页数，混合类型，允许动态清理线程，相当容易地进行写复制（copy-on-&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;write），并保持页面的清晰简洁概述。 &lt;/del&gt;它也用作列出页面类型的反向页面映射表。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;也可以不是只跟踪代表页的位，或者只跟踪 [[stack|栈]]上的页码，而是使用一个大的结构数组来表示内存。 在这些页面框架结构中，存储指向下一页的单个链接 (指针大小) 和指示其状态的8-16位信息块。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;还包括虚拟页指针和页码所属的TCB（译者注：应该是Thread Control Block-线程控制块）。 &lt;/ins&gt;保留指向每种类型页面的指针，指向列表的开始和结尾。 通过这种方式，你可以轻松地显示有关其内容的信息，每种类型的可用页数，混合类型，允许动态清理线程，相当容易地进行写复制（copy-on-&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;write），并保持页面的清晰简洁一览。 &lt;/ins&gt;它也用作列出页面类型的反向页面映射表。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;有关示例实现，请参见AtlantisOS 0.0.2或更高版本。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;有关示例实现，请参见AtlantisOS 0.0.2或更高版本。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l73&quot;&gt;第73行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第73行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Image:Tree based.png|none]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Image:Tree based.png|none]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;虽然在这样的平衡树中插入/删除需要比链表操作更复杂的操作，但通常搜索链表的时间复杂度为O(log2(N)) &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;而不是O&lt;/del&gt;(N) &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;来 &lt;/del&gt;-- 也就是说，本来如果你有1000个条目，则需要1000次迭代来扫描列表，而用树算法只需要10次迭代来查找树中的给定间隔。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;虽然在这样的平衡树中插入/删除需要比链表操作更复杂的操作，但通常搜索链表的时间复杂度为O(log2(N)) &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;，而不是链表的O&lt;/ins&gt;(N) &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;-- 也就是说，本来如果你有1000个条目，则需要1000次迭代来扫描列表，而用树算法只需要10次迭代来查找树中的给定间隔。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Linux使用AVL树进行虚拟地址管理已有相当一段时间了。 但是请注意，它将其用于regions(例如在/proc/xxxx/maps中找到的内容)，而不是用于类似malloc的接口。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Linux使用AVL树进行虚拟地址管理已有相当一段时间了。 但是请注意，它将其用于regions(例如在/proc/xxxx/maps中找到的内容)，而不是用于类似malloc的接口。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=1112&amp;oldid=prev</id>
		<title>2022年4月1日 (五) 10:00 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=1112&amp;oldid=prev"/>
		<updated>2022-04-01T10:00:23Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2022年4月1日 (五) 10:00的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l6&quot;&gt;第6行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第6行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;以下文中N字母将代表以页面为单位的内存大小。（译者注：以下介绍了几种简单的内存拆分算法）&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;以下文中N字母将代表以页面为单位的内存大小。（译者注：以下介绍了几种简单的内存拆分算法）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;使用位图 &lt;/del&gt;Bitmap ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;使用位图映射 &lt;/ins&gt;Bitmap ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;使用N/8字节的大数组用作内存使用的位映射 (即，字节#n中的位#i定义了页#n*8+i的状态)。 这样设置给定页面的状态是很快的,时间复杂度为(O(1))，分配页面可能需要时间复杂度 (O(N))。（译者注：要扫描每个位找到空闲的可被分配页）&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;使用N/8字节的大数组用作内存使用的位映射 (即，字节#n中的位#i定义了页#n*8+i的状态)。 这样设置给定页面的状态是很快的,时间复杂度为(O(1))，分配页面可能需要时间复杂度 (O(N))。（译者注：要扫描每个位找到空闲的可被分配页）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l25&quot;&gt;第25行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第25行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;甚至可以为每个部分提供1、2、甚至3或4中(或更多!)大小（sized）类型的分配（portion）。 这样你就有更多的尺寸可供选择。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;甚至可以为每个部分提供1、2、甚至3或4中(或更多!)大小（sized）类型的分配（portion）。 这样你就有更多的尺寸可供选择。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Buddy分配系统===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=&lt;/ins&gt;==Buddy分配系统===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;这是Linux内核的物理内存分配器。（译者注：Buddy算法译者也不了解，这里是字面尽量翻译，请参考其它资料！！） 可以注意到，linux分配有几个Buddy，具体取决于内存是适合ISA DMA，或者当前是 “内存占用较高” 还是 “普通”情况。 每个Buddy包含k个位图，每个位图指示可用的2^i大小和2^i对齐的自由页面块。 通常，linux使用从4k到512K块大小。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;这是Linux内核的物理内存分配器。（译者注：Buddy算法译者也不了解，这里是字面尽量翻译，请参考其它资料！！） 可以注意到，linux分配有几个Buddy，具体取决于内存是适合ISA DMA，或者当前是 “内存占用较高” 还是 “普通”情况。 每个Buddy包含k个位图，每个位图指示可用的2^i大小和2^i对齐的自由页面块。 通常，linux使用从4k到512K块大小。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l36&quot;&gt;第36行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第36行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map（每位代表32K页面）&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map（每位代表32K页面）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;包含N个页面的一个Buddy大小大约是表示同一区域的Bitmap大小的两倍，但是它可以更快地定位页面集合。（译者注：如上表如果仅Bitmap只需要5字节-40位，而增加几个Buddy后，一共有40+20+10+5=75位 上图显示了一个4-buddy，其空闲页面/块表示为符号.（点号），已用页面/块表示为符号#。 当一个块包含至少一个已用子块时，它本身被标记为#&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;已用（译者注：表示此块作为整体已不可再使用），而属于较大块的子块在图中也被标记为x。（译者注：x应该是表示是残存的部分） &lt;/del&gt;假设我们要在这个Buddy上分配一个12k的region，我们将查找可用的16K块的位图 （也就是#12页，和#36页。译者注：因为只有在16K的大小能才能放入12K，所以只需要看buddy[2]的位映射情况）。 然后将buddy[2]-&amp;gt;bit[4]设置为‘已使用’。（译者注：budyy[2]的第4位映射了#12页开头的16k内存，） 现在我们只想要4个页面中的3个，所以剩余的页面返回到适当的Buddy位映射中 (也就是#12开始只还剩了一个页的映射)。 由此产生的整体Buddy是（译者注：注意12往下的几层Buddy的状态变化）：&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;包含N个页面的一个Buddy大小大约是表示同一区域的Bitmap大小的两倍，但是它可以更快地定位页面集合。（译者注：如上表如果仅Bitmap只需要5字节-40位，而增加几个Buddy后，一共有40+20+10+5=75位 上图显示了一个4-buddy，其空闲页面/块表示为符号.（点号），已用页面/块表示为符号#。 当一个块包含至少一个已用子块时，它本身被标记为#&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;已用（译者注：表示此块作为整体已不可再使用），而属于较大块的子块在图中也被标记为x。（译者注：x应该是表示是残存的部分，也是未使用的，但是标记x是用理解以后期的内存合并拆分处理） &lt;/ins&gt;假设我们要在这个Buddy上分配一个12k的region，我们将查找可用的16K块的位图 （也就是#12页，和#36页。译者注：因为只有在16K的大小能才能放入12K，所以只需要看buddy[2]的位映射情况）。 然后将buddy[2]-&amp;gt;bit[4]设置为‘已使用’。（译者注：budyy[2]的第4位映射了#12页开头的16k内存，） 现在我们只想要4个页面中的3个，所以剩余的页面返回到适当的Buddy位映射中 (也就是#12开始只还剩了一个页的映射)。 由此产生的整体Buddy是（译者注：注意12往下的几层Buddy的状态变化）：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                   0   4   8   12  16  20  24  28  32  36&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                   0   4   8   12  16  20  24  28  32  36&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l46&quot;&gt;第46行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第46行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;请注意，最初应该尽量用最大的region，因此如果Buddy[0]&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;显示为空，我们需要检查Buddy&lt;/del&gt;[1]，然后检查Buddy[2]&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;，以获得要拆分的空闲块。（译者注：Buddy算法译者也不了解，这里是字面尽量翻译，请参考其它资料）&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;请注意，最初应该尽量用最大的region，因此如果Buddy[0]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;显示为空（empty），我们需要检查Buddy&lt;/ins&gt;[1]，然后检查Buddy[2]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;，以获得要拆分的空闲块。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 混合方案 ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 混合方案 ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=1111&amp;oldid=prev</id>
		<title>2022年4月1日 (五) 09:49 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=1111&amp;oldid=prev"/>
		<updated>2022-04-01T09:49:54Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;amp;diff=1111&amp;amp;oldid=358&quot;&gt;显示更改&lt;/a&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=358&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“== 物理内存分配器 Physical Memory Allocators ==  该部分的算法将在你需要时为你提供一个新的页面帧（Frame）。 此算法的客户端通常不在意具体返回的是哪个帧，尤其是，对多个帧的请求不需要返回连续帧 (除非你正在为DMA操作 ，例如网络数据包缓冲区，分配内存)。  以下文中N字母将代表以页面为单位的内存大小。 === 位图 Bitmap ===  使用N/8字节的大数组用…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Page_Frame_Allocation&amp;diff=358&amp;oldid=prev"/>
		<updated>2022-01-31T13:35:27Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“== 物理内存分配器 Physical Memory Allocators ==  该部分的算法将在你需要时为你提供一个新的页面帧（Frame）。 此算法的客户端通常不在意具体返回的是哪个帧，尤其是，对多个帧的请求不需要返回连续帧 (除非你正在为DMA操作 ，例如网络数据包缓冲区，分配内存)。  以下文中N字母将代表以页面为单位的内存大小。 === 位图 Bitmap ===  使用N/8字节的大数组用…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 物理内存分配器 Physical Memory Allocators ==&lt;br /&gt;
&lt;br /&gt;
该部分的算法将在你需要时为你提供一个新的页面帧（Frame）。 此算法的客户端通常不在意具体返回的是哪个帧，尤其是，对多个帧的请求不需要返回连续帧 (除非你正在为DMA操作 ，例如网络数据包缓冲区，分配内存)。&lt;br /&gt;
&lt;br /&gt;
以下文中N字母将代表以页面为单位的内存大小。&lt;br /&gt;
=== 位图 Bitmap ===&lt;br /&gt;
&lt;br /&gt;
使用N/8字节的大数组用作内存使用的位映射 (即，字节 #n 中的位 #i 定义了页 #n*8+i 的状态)。 设置给定页面的状态是快速的,时间复杂度为(O(1))，分配页面可能需要时间复杂度 (O(N))。&lt;br /&gt;
&lt;br /&gt;
* uint32_t比较运算可以一次测试多达32位，从而加快分配速度&lt;br /&gt;
* 保留指向最后分配位的指针可能会提高下一次搜索的性能 (保留有关所有先前字节未成功搜索的事实的信息)&lt;br /&gt;
&lt;br /&gt;
=== 页面堆栈/列表 ===&lt;br /&gt;
&lt;br /&gt;
每个可用的物理帧的地址都存储在类似 [[stack|栈]] 的动态结构中。 分配页面的速度很快，时间复杂度 (O(1))，也可以释放页面，但是检查页面的状态是不切实际的，除非存储了按物理地址排序的其他元数据。&lt;br /&gt;
&lt;br /&gt;
=== 大小部分方案 Sized Portion Scheme ===&lt;br /&gt;
&lt;br /&gt;
你将每个区域 (例如16kb) 分成 (例如) 1 8kb和2 4kb的块。 然后你分发每一块。 通过这样做，你可以找到更接近精确尺寸的适合。 这意味着更少的浪费。 所以说你有32kb的面积&lt;br /&gt;
&lt;br /&gt;
[[Image:Sized Portion Scheme.png]]&lt;br /&gt;
&lt;br /&gt;
你甚至可以为每个部分提供1、2、甚至3或4 (或更多!) 类型的布局。 这样你就有更多的尺寸可供选择。&lt;br /&gt;
&lt;br /&gt;
=== Buddy Allocation System 好友分配系统 ===&lt;br /&gt;
这是linux内核的物理内存分配器。 请注意，linux有几个伙伴，具体取决于内存是否适合ISA DMA，还是来自 “高物理内存” 或只是 “正常”。 每个好友包含k个位图，每个位图指示可用的2 ^ i大小和2 ^ i对齐的自由页面块。 通常，linux使用从4k到512K块。&lt;br /&gt;
&lt;br /&gt;
                  0   4   8   12  16  20  24  28  32  36&lt;br /&gt;
                  ###.#....#........#...###...########.... real memory pattern&lt;br /&gt;
 &lt;br /&gt;
    buddy[0]---&amp;gt;  ###.#.xx.#xxxxxxxx#.xx###.xx########xxxx 5  free 4K , 5-byte bitmap&lt;br /&gt;
    buddy[1]---&amp;gt;  # # # . # . x x . # . # # . # # # # x x  5  free 8K , 20-bits map&lt;br /&gt;
    buddy[2]---&amp;gt;  #   #   #   .   #   #   #   #   #   .    2  free 16K, 10-bits map&lt;br /&gt;
    buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map&lt;br /&gt;
&lt;br /&gt;
A buddy for N pages is about twice the size of a bitmap for the same area, but it allows a faster location of collections of pages. The figure above shows a 4-buddy with free pages/blocks denoted as . and used pages/blocks denoted as #. When a block contains at least one used sub-block, it is itself marked as used and sub-blocks that are part of a larger block are also marked as used (x in the figure). Say we want to allocate a 12-K region on this buddy, we'll look up the bitmap of free 16K blocks (which says we have one such starting at page #12 and another starting at page #36). buddy[2]-&amp;gt;bit[4] is then set to 'used'. Now we only want 3 pages out of the 4 we got, so the remaining page is returned to the appropriated buddy bitmap (e.g. the single pages map). The resulting buddy is&lt;br /&gt;
&lt;br /&gt;
                  0   4   8   12  16  20  24  28  32  36&lt;br /&gt;
                  ###.#....#..###...#...###...########.... real memory pattern&lt;br /&gt;
 &lt;br /&gt;
    buddy[0]---&amp;gt;  ###.#.xx.#xx###.xx#.xx###.xx########xxxx 6  free 4K , 5-byte bitmap&lt;br /&gt;
    buddy[1]---&amp;gt;  # # # . # . # # . # . # # . # # # # x x  5  free 8K , 20-bits map&lt;br /&gt;
    buddy[2]---&amp;gt;  #   #   #   #   #   #   #   #   #   .    1  free 16K, 10-bits map&lt;br /&gt;
    buddy[3]---&amp;gt;  #       #       #       #       #        0  free 32K, 5-bits map&lt;br /&gt;
&lt;br /&gt;
Note that initially, only the largest regions are available, so if buddy[0] is apparently empty, we need to check buddy[1], then buddy[2] etc. for a free block to be split.&lt;br /&gt;
&lt;br /&gt;
=== 混合方案 ===&lt;br /&gt;
&lt;br /&gt;
分配器可以被链接，以便 (例如) [[stack|栈]] 仅覆盖最后的操作，并且堆栈的 “底部” 被提交到位图 (用于紧凑存储)。 如果栈缺少页面，它可以扫描位图以找到一些 (可能在后台作业中)。&lt;br /&gt;
&lt;br /&gt;
=== 混合方案 #2 ===&lt;br /&gt;
&lt;br /&gt;
而不是只跟踪代表页的位，或者只跟踪 [[堆栈]] 上的页码，而是使用一个大的结构数组来表示内存。 在这些页面框架结构中，存储指向下一页的单个链接 (指针大小) 和指示其状态的8-16位信息块。 还包括虚拟页指针和页码所属的TCB。 保留指向每种类型页面的指针，指向列表的开始和结尾。 通过这种方式，你可以轻松地显示有关其内容的信息，每种类型的可用页数，混合类型，允许动态清理线程，相当容易地进行写复制，并保持页面的清晰简洁概述。 它也用作列出页面类型的反向页面映射表。&lt;br /&gt;
&lt;br /&gt;
有关示例实现，请参见AtlantisOS 0.0.2或更高版本。&lt;br /&gt;
&lt;br /&gt;
== 虚拟地址分配器 ==&lt;br /&gt;
=== Flat List 平展列表 ===&lt;br /&gt;
&lt;br /&gt;
管理地址空间的大区域的一种直接方法是链表 (如下所示)。 每个 “自由” 区域都与给出其大小和基址的描述符相关联。 当需要分配某些空间时，使用 “第一拟合” 或 “最佳拟合” (或其他) 算法扫描列表以寻找足够大的区域。 这是例如ms-dos管理内存的方式。 分配内存时，适当的条目要么被删除 (整个区域被分配)，要么被调整大小 (仅分配区域的一部分)。&lt;br /&gt;
&lt;br /&gt;
请注意，对于平面链接列表，“是地址XXX的内存” 或 “在哪里可以得到一个大小为YYY的块” 问题可能需要对列表进行完整遍历才能得到答案。 如果虚拟内存变得支离破碎，列表变长，这可能会成为一个问题。 “地址XXX处的内存是免费的吗？” 主要用于在释放块时将两个空闲区域合并为一个新的 (更大的) 区域，并且如果列表由不断增长的地址保持顺序，则更容易处理。&lt;br /&gt;
&lt;br /&gt;
[[Image:Flat_list.png]]&lt;br /&gt;
&lt;br /&gt;
=== 基于树的方法 ===&lt;br /&gt;
&lt;br /&gt;
由于经常在列表中搜索给定地址或给定大小，因此使用更有效的数据结构可能会很有趣。 其中一个仍然保持遍历整个列表的能力是AVL树。 AVL树中的每个 “节点” 将描述一个内存区域，并具有指向较低节点的子树和较高节点的子树的指针。&lt;br /&gt;
&lt;br /&gt;
[[Image:Tree based.png|none]]&lt;br /&gt;
&lt;br /&gt;
虽然在这样的平衡树中插入/删除需要比链表操作更复杂的操作，但通常使用O(log2(N)) 而不是O(N) 来搜索链表 -- 也就是说，如果你有1000个条目，则需要1000次迭代来扫描列表，以对照10次迭代来查找树中的给定间隔。&lt;br /&gt;
&lt;br /&gt;
Linux使用AVL树进行虚拟地址管理已有相当一段时间了。 但是请注意，它将其用于区域 (例如在/proc/xxxx/maps中找到的内容)，而不是用于类似malloc的接口。&lt;br /&gt;
&lt;br /&gt;
== 另见 ==&lt;br /&gt;
=== 文章 ===&lt;br /&gt;
* [[Memory Allocation]]&lt;br /&gt;
* [[Memory management]]&lt;br /&gt;
* [[Writing a memory manager]] - a tutorial&lt;br /&gt;
&lt;br /&gt;
=== 论坛主题 ===&lt;br /&gt;
* [[Topic:11320|Allocating memory for an allocator without an allocator]]&lt;br /&gt;
* [[Topic:9450|A bitmap based allocation technique]]&lt;br /&gt;
* [[Topic:8489|Ways to keep track of allocated RAM]]&lt;br /&gt;
* [[Topic:8463|Questions about Memory Allocation]]&lt;br /&gt;
* [[Topic:8387|Memory Management]]&lt;br /&gt;
* [[Topic:8325|Memory Management to the X'th]]&lt;br /&gt;
* [[Topic:9036|MM Questions]]&lt;br /&gt;
* [[Topic:8741|(about)Tim Robinson Memory Management Tutorial #1]]&lt;br /&gt;
* [[Topic:9781|Managing used/free pages]]&lt;br /&gt;
* [[Topic:10279|Malloc, etc. (tute by curufir)]]&lt;br /&gt;
* [[Topic:10747|Physical MM (by Freanan)]]&lt;br /&gt;
* [[Post:195116|Concepts and key points on alternative memory management schemes]]&lt;br /&gt;
&lt;br /&gt;
=== 外部链接 ===&lt;br /&gt;
*mystran's [http://replay.web.archive.org/20081206102136/http://www.cs.hut.fi/~tvoipio/memtutor.html Basic VMM for Dummies (cached)]&lt;br /&gt;
* [[wikipedia:Page replacement algorithm|Page replacement algorithm]] on Wikipedia&lt;br /&gt;
&lt;br /&gt;
[[Category:Common_Algorithms]]&lt;br /&gt;
[[Category:Memory management]]&lt;br /&gt;
[[de:Physische Speicherverwaltung]]&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>