什么是内存分配算法?首次适应、最佳适应、最坏适应

这是"操作系统系列教程"的第三十七篇。前面几篇我们讲了分页、分段、段页式、页表、缺页中断、页面置换算法、内存碎片和交换空间。这些机制解决的是"内存怎么用"的问题。但还有一个更基础的问题没有回答:当程序需要一块内存时,操作系统到底怎么从空闲内存中找到一块合适的区域分配给它?这就是------内存分配算法要解决的问题。

一个"找车位"的问题

先来想象一个场景。你开车去商场,停车场里有很多空位,但大小不一、位置分散。你需要找一个车位停车。你会怎么找?

  • 方式一:从入口开始,看到第一个能停进去的车位就停。简单快速,但可能把大车位占用了,后面来了一辆大车就停不进去。
  • 方式二:转一圈,找一个大小最接近你车长的车位。浪费最少,但找起来费时间。
  • 方式三:找一个最大的车位停进去。这样剩下的车位还很大,但大车位很快就被用完了。

这三种方式,对应操作系统中的三种经典内存分配算法:首次适应 (First Fit)、最佳适应 (Best Fit)和最坏适应(Worst Fit)。

内存分配算法是操作系统内存管理的基础。无论是分页、分段,还是动态分区,都需要一套算法来决定"从空闲内存中选哪一块"分配给请求者。选得好,内存利用率高,碎片少;选得不好,内存浪费严重,甚至无法满足分配请求。

这篇文章,我们就来把"内存分配算法"这件事讲清楚。

说明:本文涉及动态分区、空闲链表、碎片等概念。初学者如果遇到暂时看不懂的术语,可以先跳过细节,重点理解"操作系统从空闲内存中选一块分配给程序,不同选择策略就是不同的分配算法"这一核心思想。

一、内存分配算法到底是什么?

1.1 从"空闲内存管理"说起

在动态分区分配中,操作系统维护一张空闲分区表 或空闲分区链表,记录当前所有空闲内存块的位置和大小。

当程序请求一块大小为 N 的内存时,操作系统需要:

  1. 在空闲分区表/链表中查找;
  2. 找到一块大小 ≥ N 的空闲区域;
  3. 把这块区域的一部分(或全部)分配给程序;
  4. 更新空闲分区表/链表。

选择哪一块空闲区域,就是内存分配算法的核心问题。

1.2 内存分配算法的定义

给出一个正式的定义:

内存分配算法是操作系统在收到内存分配请求时,从空闲内存区域中选择一块合适的区域分配给请求者的策略。不同的选择策略会影响内存利用率、碎片数量和分配速度。

这个定义里有四个关键点:

  1. 分配请求:程序请求一块内存;
  2. 空闲区域:操作系统维护的空闲内存块;
  3. 选择策略:决定用哪一块;
  4. 影响:影响内存利用率、碎片和性能。

1.3 内存分配算法在系统中的位置

#mermaid-svg-AXVnklRFqoEEoEwi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AXVnklRFqoEEoEwi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AXVnklRFqoEEoEwi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AXVnklRFqoEEoEwi .error-icon{fill:#552222;}#mermaid-svg-AXVnklRFqoEEoEwi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AXVnklRFqoEEoEwi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AXVnklRFqoEEoEwi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AXVnklRFqoEEoEwi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AXVnklRFqoEEoEwi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AXVnklRFqoEEoEwi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AXVnklRFqoEEoEwi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AXVnklRFqoEEoEwi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AXVnklRFqoEEoEwi .marker.cross{stroke:#333333;}#mermaid-svg-AXVnklRFqoEEoEwi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AXVnklRFqoEEoEwi p{margin:0;}#mermaid-svg-AXVnklRFqoEEoEwi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-AXVnklRFqoEEoEwi .cluster-label text{fill:#333;}#mermaid-svg-AXVnklRFqoEEoEwi .cluster-label span{color:#333;}#mermaid-svg-AXVnklRFqoEEoEwi .cluster-label span p{background-color:transparent;}#mermaid-svg-AXVnklRFqoEEoEwi .label text,#mermaid-svg-AXVnklRFqoEEoEwi span{fill:#333;color:#333;}#mermaid-svg-AXVnklRFqoEEoEwi .node rect,#mermaid-svg-AXVnklRFqoEEoEwi .node circle,#mermaid-svg-AXVnklRFqoEEoEwi .node ellipse,#mermaid-svg-AXVnklRFqoEEoEwi .node polygon,#mermaid-svg-AXVnklRFqoEEoEwi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AXVnklRFqoEEoEwi .rough-node .label text,#mermaid-svg-AXVnklRFqoEEoEwi .node .label text,#mermaid-svg-AXVnklRFqoEEoEwi .image-shape .label,#mermaid-svg-AXVnklRFqoEEoEwi .icon-shape .label{text-anchor:middle;}#mermaid-svg-AXVnklRFqoEEoEwi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AXVnklRFqoEEoEwi .rough-node .label,#mermaid-svg-AXVnklRFqoEEoEwi .node .label,#mermaid-svg-AXVnklRFqoEEoEwi .image-shape .label,#mermaid-svg-AXVnklRFqoEEoEwi .icon-shape .label{text-align:center;}#mermaid-svg-AXVnklRFqoEEoEwi .node.clickable{cursor:pointer;}#mermaid-svg-AXVnklRFqoEEoEwi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AXVnklRFqoEEoEwi .arrowheadPath{fill:#333333;}#mermaid-svg-AXVnklRFqoEEoEwi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AXVnklRFqoEEoEwi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AXVnklRFqoEEoEwi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AXVnklRFqoEEoEwi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AXVnklRFqoEEoEwi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AXVnklRFqoEEoEwi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AXVnklRFqoEEoEwi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AXVnklRFqoEEoEwi .cluster text{fill:#333;}#mermaid-svg-AXVnklRFqoEEoEwi .cluster span{color:#333;}#mermaid-svg-AXVnklRFqoEEoEwi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AXVnklRFqoEEoEwi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AXVnklRFqoEEoEwi rect.text{fill:none;stroke-width:0;}#mermaid-svg-AXVnklRFqoEEoEwi .icon-shape,#mermaid-svg-AXVnklRFqoEEoEwi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AXVnklRFqoEEoEwi .icon-shape p,#mermaid-svg-AXVnklRFqoEEoEwi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AXVnklRFqoEEoEwi .icon-shape .label rect,#mermaid-svg-AXVnklRFqoEEoEwi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AXVnklRFqoEEoEwi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AXVnklRFqoEEoEwi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AXVnklRFqoEEoEwi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 程序请求内存
操作系统
空闲分区表/链表
内存分配算法
选中一块空闲区域
分配给程序
更新空闲分区表/链表

图 1:内存分配算法在系统中的位置。 操作系统通过分配算法从空闲区域中选择一块分配给程序。

二、内存分配的三种基本策略

内存分配算法有很多种,但最基础、最经典的是三种:首次适应 、最佳适应 和最坏适应。它们的思想可以用一句话概括:

算法 核心思想
首次适应 找第一个够大的空闲块
最佳适应 找最接近请求大小的空闲块
最坏适应 找最大的空闲块

接下来,我们逐一详细讲解。

图 2:三种基本内存分配算法。

三、首次适应算法(First Fit)

3.1 算法思想

首次适应 (First Fit)的核心思想是:从空闲分区链表的头部开始查找,找到第一个大小 ≥ 请求大小的空闲块,就分配给它。

简单来说,就是"第一个够大的就给它"。

3.2 算法流程

空闲链表 操作系统 程序 空闲链表 操作系统 程序 #mermaid-svg-WHP2B8VZYehZCVqE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WHP2B8VZYehZCVqE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WHP2B8VZYehZCVqE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WHP2B8VZYehZCVqE .error-icon{fill:#552222;}#mermaid-svg-WHP2B8VZYehZCVqE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WHP2B8VZYehZCVqE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WHP2B8VZYehZCVqE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WHP2B8VZYehZCVqE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WHP2B8VZYehZCVqE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WHP2B8VZYehZCVqE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WHP2B8VZYehZCVqE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WHP2B8VZYehZCVqE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WHP2B8VZYehZCVqE .marker.cross{stroke:#333333;}#mermaid-svg-WHP2B8VZYehZCVqE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WHP2B8VZYehZCVqE p{margin:0;}#mermaid-svg-WHP2B8VZYehZCVqE .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WHP2B8VZYehZCVqE text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-WHP2B8VZYehZCVqE .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-WHP2B8VZYehZCVqE .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-WHP2B8VZYehZCVqE .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-WHP2B8VZYehZCVqE .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-WHP2B8VZYehZCVqE #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-WHP2B8VZYehZCVqE .sequenceNumber{fill:white;}#mermaid-svg-WHP2B8VZYehZCVqE #sequencenumber{fill:#333;}#mermaid-svg-WHP2B8VZYehZCVqE #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-WHP2B8VZYehZCVqE .messageText{fill:#333;stroke:none;}#mermaid-svg-WHP2B8VZYehZCVqE .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WHP2B8VZYehZCVqE .labelText,#mermaid-svg-WHP2B8VZYehZCVqE .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-WHP2B8VZYehZCVqE .loopText,#mermaid-svg-WHP2B8VZYehZCVqE .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-WHP2B8VZYehZCVqE .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-WHP2B8VZYehZCVqE .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-WHP2B8VZYehZCVqE .noteText,#mermaid-svg-WHP2B8VZYehZCVqE .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-WHP2B8VZYehZCVqE .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WHP2B8VZYehZCVqE .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WHP2B8VZYehZCVqE .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WHP2B8VZYehZCVqE .actorPopupMenu{position:absolute;}#mermaid-svg-WHP2B8VZYehZCVqE .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-WHP2B8VZYehZCVqE .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WHP2B8VZYehZCVqE .actor-man circle,#mermaid-svg-WHP2B8VZYehZCVqE line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-WHP2B8VZYehZCVqE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} altS \>= NS \< N loop遍历每个空闲块 请求大小 N从头开始遍历当前块大小 S选中该块分配成功继续下一个分配失败(无合适块)

图 3:首次适应算法的流程。

3.3 一个具体的例子

假设空闲分区链表如下(按地址顺序):

空闲块 起始地址 大小
A 0x0000 100KB
B 0x1000 50KB
C 0x2000 200KB
D 0x3000 80KB

现在有一个程序请求 60KB 内存。

首次适应算法从头开始遍历:

  1. 块 A(100KB)≥ 60KB,选中 A;
  2. 从 A 中分配 60KB,剩余 40KB;
  3. 更新空闲链表:A 变为 40KB,B、C、D 不变。

#mermaid-svg-we99hPjJXeZ9a6pH{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-we99hPjJXeZ9a6pH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-we99hPjJXeZ9a6pH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-we99hPjJXeZ9a6pH .error-icon{fill:#552222;}#mermaid-svg-we99hPjJXeZ9a6pH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-we99hPjJXeZ9a6pH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-we99hPjJXeZ9a6pH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-we99hPjJXeZ9a6pH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-we99hPjJXeZ9a6pH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-we99hPjJXeZ9a6pH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-we99hPjJXeZ9a6pH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-we99hPjJXeZ9a6pH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-we99hPjJXeZ9a6pH .marker.cross{stroke:#333333;}#mermaid-svg-we99hPjJXeZ9a6pH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-we99hPjJXeZ9a6pH p{margin:0;}#mermaid-svg-we99hPjJXeZ9a6pH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-we99hPjJXeZ9a6pH .cluster-label text{fill:#333;}#mermaid-svg-we99hPjJXeZ9a6pH .cluster-label span{color:#333;}#mermaid-svg-we99hPjJXeZ9a6pH .cluster-label span p{background-color:transparent;}#mermaid-svg-we99hPjJXeZ9a6pH .label text,#mermaid-svg-we99hPjJXeZ9a6pH span{fill:#333;color:#333;}#mermaid-svg-we99hPjJXeZ9a6pH .node rect,#mermaid-svg-we99hPjJXeZ9a6pH .node circle,#mermaid-svg-we99hPjJXeZ9a6pH .node ellipse,#mermaid-svg-we99hPjJXeZ9a6pH .node polygon,#mermaid-svg-we99hPjJXeZ9a6pH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-we99hPjJXeZ9a6pH .rough-node .label text,#mermaid-svg-we99hPjJXeZ9a6pH .node .label text,#mermaid-svg-we99hPjJXeZ9a6pH .image-shape .label,#mermaid-svg-we99hPjJXeZ9a6pH .icon-shape .label{text-anchor:middle;}#mermaid-svg-we99hPjJXeZ9a6pH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-we99hPjJXeZ9a6pH .rough-node .label,#mermaid-svg-we99hPjJXeZ9a6pH .node .label,#mermaid-svg-we99hPjJXeZ9a6pH .image-shape .label,#mermaid-svg-we99hPjJXeZ9a6pH .icon-shape .label{text-align:center;}#mermaid-svg-we99hPjJXeZ9a6pH .node.clickable{cursor:pointer;}#mermaid-svg-we99hPjJXeZ9a6pH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-we99hPjJXeZ9a6pH .arrowheadPath{fill:#333333;}#mermaid-svg-we99hPjJXeZ9a6pH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-we99hPjJXeZ9a6pH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-we99hPjJXeZ9a6pH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-we99hPjJXeZ9a6pH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-we99hPjJXeZ9a6pH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-we99hPjJXeZ9a6pH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-we99hPjJXeZ9a6pH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-we99hPjJXeZ9a6pH .cluster text{fill:#333;}#mermaid-svg-we99hPjJXeZ9a6pH .cluster span{color:#333;}#mermaid-svg-we99hPjJXeZ9a6pH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-we99hPjJXeZ9a6pH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-we99hPjJXeZ9a6pH rect.text{fill:none;stroke-width:0;}#mermaid-svg-we99hPjJXeZ9a6pH .icon-shape,#mermaid-svg-we99hPjJXeZ9a6pH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-we99hPjJXeZ9a6pH .icon-shape p,#mermaid-svg-we99hPjJXeZ9a6pH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-we99hPjJXeZ9a6pH .icon-shape .label rect,#mermaid-svg-we99hPjJXeZ9a6pH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-we99hPjJXeZ9a6pH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-we99hPjJXeZ9a6pH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-we99hPjJXeZ9a6pH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 分配 60KB
空闲块 A: 100KB
空闲块 B: 50KB
空闲块 C: 200KB
空闲块 D: 80KB
分配后 A: 40KB
空闲块 B: 50KB
空闲块 C: 200KB
空闲块 D: 80KB

图 4:首次适应算法示例。 请求 60KB,选中第一个够大的块 A。

3.4 首次适应的优缺点

优点 说明
实现简单 从头遍历,找到就分配
速度快 通常不需要遍历整个链表
大块保留 倾向于保留高地址的大空闲块
缺点 说明
低地址碎片多 低地址区域容易被反复分割,产生大量小碎片
分配不均匀 高地址区域很少被使用

关键特点 :首次适应算法倾向于优先使用低地址的空闲区域,导致低地址区域碎片化严重,高地址区域保留大块空闲。

四、最佳适应算法(Best Fit)

4.1 算法思想

最佳适应 (Best Fit)的核心思想是:遍历整个空闲分区链表,找到大小最接近请求大小的空闲块,分配给它。

简单来说,就是"最合适的就给它"。这样分配的剩余空间最小,浪费最少。

4.2 算法流程

空闲链表 操作系统 程序 空闲链表 操作系统 程序 #mermaid-svg-h5G9gKQ5P5O9n0O9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .error-icon{fill:#552222;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .marker.cross{stroke:#333333;}#mermaid-svg-h5G9gKQ5P5O9n0O9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-h5G9gKQ5P5O9n0O9 p{margin:0;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-h5G9gKQ5P5O9n0O9 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-h5G9gKQ5P5O9n0O9 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-h5G9gKQ5P5O9n0O9 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .sequenceNumber{fill:white;}#mermaid-svg-h5G9gKQ5P5O9n0O9 #sequencenumber{fill:#333;}#mermaid-svg-h5G9gKQ5P5O9n0O9 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .messageText{fill:#333;stroke:none;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .labelText,#mermaid-svg-h5G9gKQ5P5O9n0O9 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .loopText,#mermaid-svg-h5G9gKQ5P5O9n0O9 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-h5G9gKQ5P5O9n0O9 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .noteText,#mermaid-svg-h5G9gKQ5P5O9n0O9 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .actorPopupMenu{position:absolute;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-h5G9gKQ5P5O9n0O9 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-h5G9gKQ5P5O9n0O9 .actor-man circle,#mermaid-svg-h5G9gKQ5P5O9n0O9 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-h5G9gKQ5P5O9n0O9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} loop遍历每个空闲块 请求大小 N遍历整个链表当前块大小 S记录最小满足 S >= N 的块选中最小满足的块分配成功

图 5:最佳适应算法的流程。

4.3 一个具体的例子

同样假设空闲分区链表如下:

空闲块 起始地址 大小
A 0x0000 100KB
B 0x1000 50KB
C 0x2000 200KB
D 0x3000 80KB

程序请求 60KB 内存。

最佳适应算法遍历整个链表:

  1. 块 A(100KB)≥ 60KB,候选,剩余 40KB;
  2. 块 B(50KB)< 60KB,跳过;
  3. 块 C(200KB)≥ 60KB,候选,剩余 140KB;
  4. 块 D(80KB)≥ 60KB,候选,剩余 20KB;
  5. 选择剩余最小的块 D,分配 60KB,剩余 20KB。

#mermaid-svg-NTxNmAAgTXrGJXHD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NTxNmAAgTXrGJXHD .error-icon{fill:#552222;}#mermaid-svg-NTxNmAAgTXrGJXHD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NTxNmAAgTXrGJXHD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NTxNmAAgTXrGJXHD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NTxNmAAgTXrGJXHD .marker.cross{stroke:#333333;}#mermaid-svg-NTxNmAAgTXrGJXHD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NTxNmAAgTXrGJXHD p{margin:0;}#mermaid-svg-NTxNmAAgTXrGJXHD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-NTxNmAAgTXrGJXHD .cluster-label text{fill:#333;}#mermaid-svg-NTxNmAAgTXrGJXHD .cluster-label span{color:#333;}#mermaid-svg-NTxNmAAgTXrGJXHD .cluster-label span p{background-color:transparent;}#mermaid-svg-NTxNmAAgTXrGJXHD .label text,#mermaid-svg-NTxNmAAgTXrGJXHD span{fill:#333;color:#333;}#mermaid-svg-NTxNmAAgTXrGJXHD .node rect,#mermaid-svg-NTxNmAAgTXrGJXHD .node circle,#mermaid-svg-NTxNmAAgTXrGJXHD .node ellipse,#mermaid-svg-NTxNmAAgTXrGJXHD .node polygon,#mermaid-svg-NTxNmAAgTXrGJXHD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NTxNmAAgTXrGJXHD .rough-node .label text,#mermaid-svg-NTxNmAAgTXrGJXHD .node .label text,#mermaid-svg-NTxNmAAgTXrGJXHD .image-shape .label,#mermaid-svg-NTxNmAAgTXrGJXHD .icon-shape .label{text-anchor:middle;}#mermaid-svg-NTxNmAAgTXrGJXHD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NTxNmAAgTXrGJXHD .rough-node .label,#mermaid-svg-NTxNmAAgTXrGJXHD .node .label,#mermaid-svg-NTxNmAAgTXrGJXHD .image-shape .label,#mermaid-svg-NTxNmAAgTXrGJXHD .icon-shape .label{text-align:center;}#mermaid-svg-NTxNmAAgTXrGJXHD .node.clickable{cursor:pointer;}#mermaid-svg-NTxNmAAgTXrGJXHD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NTxNmAAgTXrGJXHD .arrowheadPath{fill:#333333;}#mermaid-svg-NTxNmAAgTXrGJXHD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NTxNmAAgTXrGJXHD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NTxNmAAgTXrGJXHD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NTxNmAAgTXrGJXHD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NTxNmAAgTXrGJXHD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NTxNmAAgTXrGJXHD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NTxNmAAgTXrGJXHD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NTxNmAAgTXrGJXHD .cluster text{fill:#333;}#mermaid-svg-NTxNmAAgTXrGJXHD .cluster span{color:#333;}#mermaid-svg-NTxNmAAgTXrGJXHD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NTxNmAAgTXrGJXHD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NTxNmAAgTXrGJXHD rect.text{fill:none;stroke-width:0;}#mermaid-svg-NTxNmAAgTXrGJXHD .icon-shape,#mermaid-svg-NTxNmAAgTXrGJXHD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NTxNmAAgTXrGJXHD .icon-shape p,#mermaid-svg-NTxNmAAgTXrGJXHD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NTxNmAAgTXrGJXHD .icon-shape .label rect,#mermaid-svg-NTxNmAAgTXrGJXHD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NTxNmAAgTXrGJXHD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NTxNmAAgTXrGJXHD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NTxNmAAgTXrGJXHD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 分配 60KB
空闲块 A: 100KB
空闲块 B: 50KB
空闲块 C: 200KB
空闲块 D: 80KB
分配后 D: 20KB
空闲块 A: 100KB
空闲块 B: 50KB
空闲块 C: 200KB

图 6:最佳适应算法示例。 请求 60KB,选中剩余最小的块 D。

4.4 最佳适应的优缺点

优点 说明
浪费最少 分配的剩余空间最小
内存利用率高 每次分配都尽可能"刚好"
缺点 说明
外部碎片多 每次分配都留下很小的碎片
速度慢 需要遍历整个链表
小碎片无法利用 留下的碎片往往太小,无法再分配

关键特点:最佳适应算法每次都选择"最合适"的块,但留下的碎片也最小,最终会积累大量无法利用的小碎片,反而降低内存利用率。这就是所谓的"最佳适应算法并不最佳"。

五、最坏适应算法(Worst Fit)

5.1 算法思想

最坏适应 (Worst Fit)的核心思想是:遍历整个空闲分区链表,找到最大的空闲块,分配给它。

简单来说,就是"最大的就给它"。这样分配的剩余空间仍然很大,可以继续被利用。

5.2 算法流程

空闲链表 操作系统 程序 空闲链表 操作系统 程序 #mermaid-svg-0e6KJvwdTlNRmIg4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0e6KJvwdTlNRmIg4 .error-icon{fill:#552222;}#mermaid-svg-0e6KJvwdTlNRmIg4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0e6KJvwdTlNRmIg4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0e6KJvwdTlNRmIg4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0e6KJvwdTlNRmIg4 .marker.cross{stroke:#333333;}#mermaid-svg-0e6KJvwdTlNRmIg4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0e6KJvwdTlNRmIg4 p{margin:0;}#mermaid-svg-0e6KJvwdTlNRmIg4 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0e6KJvwdTlNRmIg4 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-0e6KJvwdTlNRmIg4 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-0e6KJvwdTlNRmIg4 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-0e6KJvwdTlNRmIg4 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-0e6KJvwdTlNRmIg4 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-0e6KJvwdTlNRmIg4 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-0e6KJvwdTlNRmIg4 .sequenceNumber{fill:white;}#mermaid-svg-0e6KJvwdTlNRmIg4 #sequencenumber{fill:#333;}#mermaid-svg-0e6KJvwdTlNRmIg4 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-0e6KJvwdTlNRmIg4 .messageText{fill:#333;stroke:none;}#mermaid-svg-0e6KJvwdTlNRmIg4 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0e6KJvwdTlNRmIg4 .labelText,#mermaid-svg-0e6KJvwdTlNRmIg4 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-0e6KJvwdTlNRmIg4 .loopText,#mermaid-svg-0e6KJvwdTlNRmIg4 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-0e6KJvwdTlNRmIg4 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-0e6KJvwdTlNRmIg4 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-0e6KJvwdTlNRmIg4 .noteText,#mermaid-svg-0e6KJvwdTlNRmIg4 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-0e6KJvwdTlNRmIg4 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0e6KJvwdTlNRmIg4 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0e6KJvwdTlNRmIg4 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0e6KJvwdTlNRmIg4 .actorPopupMenu{position:absolute;}#mermaid-svg-0e6KJvwdTlNRmIg4 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-0e6KJvwdTlNRmIg4 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0e6KJvwdTlNRmIg4 .actor-man circle,#mermaid-svg-0e6KJvwdTlNRmIg4 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-0e6KJvwdTlNRmIg4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} loop遍历每个空闲-块 请求大小 N遍历整个链表当前块大小 S记录最大的块选中最大的块分配成功

图 7:最坏适应算法的流程。

5.3 一个具体的例子

同样假设空闲分区链表如下:

空闲块 起始地址 大小
A 0x0000 100KB
B 0x1000 50KB
C 0x2000 200KB
D 0x3000 80KB

程序请求 60KB 内存。

最坏适应算法遍历整个链表:

  1. 最大的块是 C(200KB),选中 C;
  2. 从 C 中分配 60KB,剩余 140KB;
  3. 更新空闲链表:C 变为 140KB。

#mermaid-svg-8uEm1ASf9NxrUZix{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8uEm1ASf9NxrUZix .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8uEm1ASf9NxrUZix .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8uEm1ASf9NxrUZix .error-icon{fill:#552222;}#mermaid-svg-8uEm1ASf9NxrUZix .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8uEm1ASf9NxrUZix .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8uEm1ASf9NxrUZix .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8uEm1ASf9NxrUZix .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8uEm1ASf9NxrUZix .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8uEm1ASf9NxrUZix .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8uEm1ASf9NxrUZix .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8uEm1ASf9NxrUZix .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8uEm1ASf9NxrUZix .marker.cross{stroke:#333333;}#mermaid-svg-8uEm1ASf9NxrUZix svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8uEm1ASf9NxrUZix p{margin:0;}#mermaid-svg-8uEm1ASf9NxrUZix .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8uEm1ASf9NxrUZix .cluster-label text{fill:#333;}#mermaid-svg-8uEm1ASf9NxrUZix .cluster-label span{color:#333;}#mermaid-svg-8uEm1ASf9NxrUZix .cluster-label span p{background-color:transparent;}#mermaid-svg-8uEm1ASf9NxrUZix .label text,#mermaid-svg-8uEm1ASf9NxrUZix span{fill:#333;color:#333;}#mermaid-svg-8uEm1ASf9NxrUZix .node rect,#mermaid-svg-8uEm1ASf9NxrUZix .node circle,#mermaid-svg-8uEm1ASf9NxrUZix .node ellipse,#mermaid-svg-8uEm1ASf9NxrUZix .node polygon,#mermaid-svg-8uEm1ASf9NxrUZix .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8uEm1ASf9NxrUZix .rough-node .label text,#mermaid-svg-8uEm1ASf9NxrUZix .node .label text,#mermaid-svg-8uEm1ASf9NxrUZix .image-shape .label,#mermaid-svg-8uEm1ASf9NxrUZix .icon-shape .label{text-anchor:middle;}#mermaid-svg-8uEm1ASf9NxrUZix .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8uEm1ASf9NxrUZix .rough-node .label,#mermaid-svg-8uEm1ASf9NxrUZix .node .label,#mermaid-svg-8uEm1ASf9NxrUZix .image-shape .label,#mermaid-svg-8uEm1ASf9NxrUZix .icon-shape .label{text-align:center;}#mermaid-svg-8uEm1ASf9NxrUZix .node.clickable{cursor:pointer;}#mermaid-svg-8uEm1ASf9NxrUZix .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8uEm1ASf9NxrUZix .arrowheadPath{fill:#333333;}#mermaid-svg-8uEm1ASf9NxrUZix .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8uEm1ASf9NxrUZix .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8uEm1ASf9NxrUZix .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8uEm1ASf9NxrUZix .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8uEm1ASf9NxrUZix .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8uEm1ASf9NxrUZix .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8uEm1ASf9NxrUZix .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8uEm1ASf9NxrUZix .cluster text{fill:#333;}#mermaid-svg-8uEm1ASf9NxrUZix .cluster span{color:#333;}#mermaid-svg-8uEm1ASf9NxrUZix div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8uEm1ASf9NxrUZix .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8uEm1ASf9NxrUZix rect.text{fill:none;stroke-width:0;}#mermaid-svg-8uEm1ASf9NxrUZix .icon-shape,#mermaid-svg-8uEm1ASf9NxrUZix .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8uEm1ASf9NxrUZix .icon-shape p,#mermaid-svg-8uEm1ASf9NxrUZix .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8uEm1ASf9NxrUZix .icon-shape .label rect,#mermaid-svg-8uEm1ASf9NxrUZix .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8uEm1ASf9NxrUZix .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8uEm1ASf9NxrUZix .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8uEm1ASf9NxrUZix :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 分配 60KB
空闲块 A: 100KB
空闲块 B: 50KB
空闲块 C: 200KB
空闲块 D: 80KB
分配后 C: 140KB
空闲块 A: 100KB
空闲块 B: 50KB
空闲块 D: 80KB

图 8:最坏适应算法示例。 请求 60KB,选中最大的块 C。

5.4 最坏适应的优缺点

优点 说明
剩余块大 分配后剩余空间仍较大,可继续利用
减少小碎片 避免产生太小无法使用的碎片
缺点 说明
大块很快耗尽 最大的块被反复分割,很快就没有大块了
速度慢 需要遍历整个链表
不适合大请求 大块耗尽后,大请求无法满足

关键特点:最坏适应算法每次都"砍"最大的块,导致大块很快消失。当后续有大请求时,可能无法满足。

六、三种算法的对比

6.1 用一个例子对比

假设空闲分区链表如下:

空闲块 大小
A 100KB
B 50KB
C 200KB
D 80KB

依次有请求:60KB、40KB、100KB。

首次适应:

  1. 60KB:选 A(100KB),剩余 40KB;
  2. 40KB:选 A 剩余(40KB),刚好;
  3. 100KB:选 C(200KB),剩余 100KB。

最佳适应:

  1. 60KB:选 D(80KB),剩余 20KB;
  2. 40KB:选 B(50KB),剩余 10KB;
  3. 100KB:选 C(200KB),剩余 100KB。

最坏适应:

  1. 60KB:选 C(200KB),剩余 140KB;
  2. 40KB:选 C 剩余(140KB),剩余 100KB;
  3. 100KB:选 A(100KB),刚好。

6.2 综合对比

对比项 首次适应 最佳适应 最坏适应
查找方式 从头找到第一个够大的 遍历找最接近的 遍历找最大的
查找速度 快 慢 慢
剩余碎片 低地址碎片多 小碎片多 大块耗尽快
内存利用率 较高 理论最高,实际较低 较低
大请求支持 好(保留大块) 中 差(大块耗尽)
实现复杂度 简单 中等 中等
实际应用 常用 较少 较少

#mermaid-svg-xKPTBaBFabJUhE6R{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xKPTBaBFabJUhE6R .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xKPTBaBFabJUhE6R .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xKPTBaBFabJUhE6R .error-icon{fill:#552222;}#mermaid-svg-xKPTBaBFabJUhE6R .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xKPTBaBFabJUhE6R .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xKPTBaBFabJUhE6R .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xKPTBaBFabJUhE6R .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xKPTBaBFabJUhE6R .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xKPTBaBFabJUhE6R .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xKPTBaBFabJUhE6R .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xKPTBaBFabJUhE6R .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xKPTBaBFabJUhE6R .marker.cross{stroke:#333333;}#mermaid-svg-xKPTBaBFabJUhE6R svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xKPTBaBFabJUhE6R p{margin:0;}#mermaid-svg-xKPTBaBFabJUhE6R .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xKPTBaBFabJUhE6R .cluster-label text{fill:#333;}#mermaid-svg-xKPTBaBFabJUhE6R .cluster-label span{color:#333;}#mermaid-svg-xKPTBaBFabJUhE6R .cluster-label span p{background-color:transparent;}#mermaid-svg-xKPTBaBFabJUhE6R .label text,#mermaid-svg-xKPTBaBFabJUhE6R span{fill:#333;color:#333;}#mermaid-svg-xKPTBaBFabJUhE6R .node rect,#mermaid-svg-xKPTBaBFabJUhE6R .node circle,#mermaid-svg-xKPTBaBFabJUhE6R .node ellipse,#mermaid-svg-xKPTBaBFabJUhE6R .node polygon,#mermaid-svg-xKPTBaBFabJUhE6R .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xKPTBaBFabJUhE6R .rough-node .label text,#mermaid-svg-xKPTBaBFabJUhE6R .node .label text,#mermaid-svg-xKPTBaBFabJUhE6R .image-shape .label,#mermaid-svg-xKPTBaBFabJUhE6R .icon-shape .label{text-anchor:middle;}#mermaid-svg-xKPTBaBFabJUhE6R .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xKPTBaBFabJUhE6R .rough-node .label,#mermaid-svg-xKPTBaBFabJUhE6R .node .label,#mermaid-svg-xKPTBaBFabJUhE6R .image-shape .label,#mermaid-svg-xKPTBaBFabJUhE6R .icon-shape .label{text-align:center;}#mermaid-svg-xKPTBaBFabJUhE6R .node.clickable{cursor:pointer;}#mermaid-svg-xKPTBaBFabJUhE6R .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xKPTBaBFabJUhE6R .arrowheadPath{fill:#333333;}#mermaid-svg-xKPTBaBFabJUhE6R .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xKPTBaBFabJUhE6R .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xKPTBaBFabJUhE6R .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xKPTBaBFabJUhE6R .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xKPTBaBFabJUhE6R .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xKPTBaBFabJUhE6R .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xKPTBaBFabJUhE6R .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xKPTBaBFabJUhE6R .cluster text{fill:#333;}#mermaid-svg-xKPTBaBFabJUhE6R .cluster span{color:#333;}#mermaid-svg-xKPTBaBFabJUhE6R div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xKPTBaBFabJUhE6R .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xKPTBaBFabJUhE6R rect.text{fill:none;stroke-width:0;}#mermaid-svg-xKPTBaBFabJUhE6R .icon-shape,#mermaid-svg-xKPTBaBFabJUhE6R .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xKPTBaBFabJUhE6R .icon-shape p,#mermaid-svg-xKPTBaBFabJUhE6R .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xKPTBaBFabJUhE6R .icon-shape .label rect,#mermaid-svg-xKPTBaBFabJUhE6R .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xKPTBaBFabJUhE6R .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xKPTBaBFabJUhE6R .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xKPTBaBFabJUhE6R :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 三种算法对比
首次适应: 快, 低地址碎片多
最佳适应: 慢, 小碎片多
最坏适应: 慢, 大块耗尽快

图 9:三种内存分配算法的对比。

6.3 结论

首次适应算法通常是最好的选择,因为:

  • 实现简单,速度快;
  • 内存利用率较高;
  • 保留高地址的大块,有利于大请求。

最佳适应算法理论上浪费最少,但实际效果往往不好,因为它产生大量小碎片。

最坏适应算法很少使用,因为它很快耗尽大块,不利于后续大请求。

七、其他内存分配算法

除了三种基本算法,还有一些改进算法。

7.1 循环首次适应(Next Fit)

循环首次适应(Next Fit)是首次适应的改进版:不是每次从头开始查找,而是从上次分配的位置继续查找。

优点 :分配更均匀,避免低地址碎片化。

缺点:大块可能被过早分割。

7.2 快速适应(Quick Fit)

快速适应(Quick Fit)维护多个空闲链表,每个链表对应一种常用大小。分配时直接在对应链表中查找。

优点 :分配速度快。

缺点:链表维护复杂,合并困难。

7.3 伙伴系统(Buddy System)

伙伴系统(Buddy System)把内存按 2 的幂次划分,分配时找到最接近的 2 的幂次块。释放时,如果相邻的"伙伴"也空闲,就合并。

优点 :分配和释放快,合并简单。

缺点:内部碎片较大(只能分配 2 的幂次大小)。

算法 优点 缺点
循环首次适应 分配均匀 大块易分割
快速适应 分配快 维护复杂
伙伴系统 合并简单 内部碎片大

图 10:其他常见的内存分配算法。

八、实际应用

8.1 Linux 中的内存分配

Linux 内核使用多种分配器:

分配器 用途
伙伴系统 管理物理页框
slab 分配器 管理小对象
slub 分配器 slab 的改进版,现代内核默认
vmalloc 分配虚拟地址连续但物理不连续的内存

8.2 用户态 malloc

C 标准库的 malloc() 底层使用内存分配器,如:

  • ptmalloc:glibc 默认分配器;
  • jemalloc:Facebook 开发,适合多线程;
  • tcmalloc:Google 开发,高性能。

这些分配器内部使用多种策略,包括首次适应、快速适应等。

c 复制代码
// malloc 底层可能使用首次适应
void *ptr = malloc(1024);
// 分配器从空闲链表中找一块合适的

8.3 数据库中的内存分配

数据库系统有自己的内存池管理,通常使用伙伴系统 或slab 分配器,减少碎片并提高分配速度。
#mermaid-svg-13kTdU2fNASASyTr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-13kTdU2fNASASyTr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-13kTdU2fNASASyTr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-13kTdU2fNASASyTr .error-icon{fill:#552222;}#mermaid-svg-13kTdU2fNASASyTr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-13kTdU2fNASASyTr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-13kTdU2fNASASyTr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-13kTdU2fNASASyTr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-13kTdU2fNASASyTr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-13kTdU2fNASASyTr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-13kTdU2fNASASyTr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-13kTdU2fNASASyTr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-13kTdU2fNASASyTr .marker.cross{stroke:#333333;}#mermaid-svg-13kTdU2fNASASyTr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-13kTdU2fNASASyTr p{margin:0;}#mermaid-svg-13kTdU2fNASASyTr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-13kTdU2fNASASyTr .cluster-label text{fill:#333;}#mermaid-svg-13kTdU2fNASASyTr .cluster-label span{color:#333;}#mermaid-svg-13kTdU2fNASASyTr .cluster-label span p{background-color:transparent;}#mermaid-svg-13kTdU2fNASASyTr .label text,#mermaid-svg-13kTdU2fNASASyTr span{fill:#333;color:#333;}#mermaid-svg-13kTdU2fNASASyTr .node rect,#mermaid-svg-13kTdU2fNASASyTr .node circle,#mermaid-svg-13kTdU2fNASASyTr .node ellipse,#mermaid-svg-13kTdU2fNASASyTr .node polygon,#mermaid-svg-13kTdU2fNASASyTr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-13kTdU2fNASASyTr .rough-node .label text,#mermaid-svg-13kTdU2fNASASyTr .node .label text,#mermaid-svg-13kTdU2fNASASyTr .image-shape .label,#mermaid-svg-13kTdU2fNASASyTr .icon-shape .label{text-anchor:middle;}#mermaid-svg-13kTdU2fNASASyTr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-13kTdU2fNASASyTr .rough-node .label,#mermaid-svg-13kTdU2fNASASyTr .node .label,#mermaid-svg-13kTdU2fNASASyTr .image-shape .label,#mermaid-svg-13kTdU2fNASASyTr .icon-shape .label{text-align:center;}#mermaid-svg-13kTdU2fNASASyTr .node.clickable{cursor:pointer;}#mermaid-svg-13kTdU2fNASASyTr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-13kTdU2fNASASyTr .arrowheadPath{fill:#333333;}#mermaid-svg-13kTdU2fNASASyTr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-13kTdU2fNASASyTr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-13kTdU2fNASASyTr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-13kTdU2fNASASyTr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-13kTdU2fNASASyTr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-13kTdU2fNASASyTr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-13kTdU2fNASASyTr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-13kTdU2fNASASyTr .cluster text{fill:#333;}#mermaid-svg-13kTdU2fNASASyTr .cluster span{color:#333;}#mermaid-svg-13kTdU2fNASASyTr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-13kTdU2fNASASyTr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-13kTdU2fNASASyTr rect.text{fill:none;stroke-width:0;}#mermaid-svg-13kTdU2fNASASyTr .icon-shape,#mermaid-svg-13kTdU2fNASASyTr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-13kTdU2fNASASyTr .icon-shape p,#mermaid-svg-13kTdU2fNASASyTr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-13kTdU2fNASASyTr .icon-shape .label rect,#mermaid-svg-13kTdU2fNASASyTr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-13kTdU2fNASASyTr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-13kTdU2fNASASyTr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-13kTdU2fNASASyTr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 内存分配实际应用
Linux: 伙伴系统 + slab
用户态: ptmalloc/jemalloc/tcmalloc
数据库: 内存池

图 11:内存分配算法的实际应用。

九、常见误区澄清

误区 真相
"最佳适应算法是最好的" 理论上浪费最少,但实际产生大量小碎片
"首次适应算法效率低" 实际上首次适应速度快,内存利用率较高
"最坏适应算法能减少碎片" 它减少小碎片,但很快耗尽大块
"所有分配算法都用链表" 也有位图、树等实现方式
"分配算法只影响速度" 还影响内存利用率和碎片
"伙伴系统没有碎片" 有内部碎片,只能分配 2 的幂次大小
"malloc 就是系统调用" malloc 是库函数,底层调用 brk/mmap
相关推荐
imDwAaY1 小时前
进程之间如何“对话”?一篇讲清六种进程间通信方式
后端·操作系统
MinterFusion3 小时前
如何在开放麒麟(openKylin)下安装GTK(v0.1.0)
linux·操作系统·软件安装·gtk·明德融创·openkylin·linux图形软件开发
Teecertlabs3 小时前
【机密计算顶会解读】15:LDR——面向嵌入式TEE系统的高效安全Linux驱动
linux·操作系统·机密计算·可信执行环境
云计算练习生15 小时前
什么是内存映射(mmap)?文件和内存之间的桥梁
操作系统·内存·内存映射
寻道模式17 小时前
【运维心得】完整教程:绕过Win11限制让老机焕发新生
运维·操作系统·win11
天府云创21 小时前
Agentic开发时代到来——鸿蒙PC三大原生开发工具公测
华为·操作系统·harmonyos·鸿蒙系统·cli·deveco·agentic
imDwAaY1 天前
程序为什么会卡在死锁里?从四个必要条件到预防与解除
后端·操作系统
imDwAaY2 天前
用户态与内核态到底怎么切换?从系统调用到上下文切换
后端·操作系统
imDwAaY2 天前
进程、线程、协程有什么区别?从资源分配到调度,一篇理清
后端·操作系统