0 00:00:00,000 --> 00:00:07,320 1 00:00:07,400 --> 00:00:11,160 接下来我们讨论碎片整理 2 00:00:11,200 --> 00:00:13,400 碎片整理是想说 3 00:00:13,440 --> 00:00:18,880 我们已经把内存分区分配给了进程 4 00:00:18,920 --> 00:00:21,520 它们也已经占定了某一个位置 5 00:00:21,560 --> 00:00:23,240 但是这个时候 6 00:00:23,280 --> 00:00:26,000 我正在执行的应用进程 7 00:00:26,040 --> 00:00:29,640 或者说新创建的进程需要内存空间 8 00:00:29,680 --> 00:00:31,040 这个时候没有了 9 00:00:31,080 --> 00:00:34,280 或者说这些都已经剩下小的碎片了 10 00:00:34,320 --> 00:00:35,760 那我想要内存空间 11 00:00:35,800 --> 00:00:36,720 这个时候怎么办 12 00:00:36,760 --> 00:00:39,960 我们可以通过碎片整理 13 00:00:40,000 --> 00:00:43,200 来获取更大的可用内存空间 14 00:00:43,240 --> 00:00:47,760 以便于满足进程的应用空间需求 15 00:00:47,800 --> 00:00:53,400 我们看碎片整理 16 00:00:53,440 --> 00:00:56,640 碎片整理是指我们通过调整 17 00:00:56,680 --> 00:01:01,000 已分配给进程的内存分区它的位置 18 00:01:01,040 --> 00:01:04,960 来减少碎片的一种做法 19 00:01:05,000 --> 00:01:07,400 这种做法有一个图示 20 00:01:07,440 --> 00:01:10,520 说这里头这几个闪烁的地方 21 00:01:10,560 --> 00:01:14,800 就在我们这里头是空闲的空间 22 00:01:14,840 --> 00:01:18,840 但是假定说这里头最大是剩三块 23 00:01:18,880 --> 00:01:21,960 但是现在我要分配一个连续四块 24 00:01:22,000 --> 00:01:23,320 那就没有了 25 00:01:23,360 --> 00:01:24,400 这个时候怎么办呢 26 00:01:24,440 --> 00:01:26,200 我们希望通过碎片整理 27 00:01:26,240 --> 00:01:27,960 我们把它压缩到一起 28 00:01:28,000 --> 00:01:31,000 然后剩的这块就可以满足要求了 29 00:01:31,040 --> 00:01:34,240 但是我要把正在内存当中的 30 00:01:34,280 --> 00:01:36,240 这些进程的位置挪动 31 00:01:36,280 --> 00:01:38,240 这个事是不可以随便弄的 32 00:01:38,280 --> 00:01:39,600 原因在于我里头 33 00:01:39,640 --> 00:01:42,040 可能有各种各样的地址引用 34 00:01:42,080 --> 00:01:44,840 这种引用用的是绝对地址的话 35 00:01:44,880 --> 00:01:46,400 那这个时候你挪了之后 36 00:01:46,440 --> 00:01:48,520 它是没办法正确运行的 37 00:01:48,560 --> 00:01:51,680 所以在这里头要进行碎片紧凑 38 00:01:51,720 --> 00:01:53,280 它是需要一些条件 39 00:01:53,320 --> 00:01:56,400 也就是说我所有这些进程 40 00:01:56,440 --> 00:02:00,360 都是可以动态重定位的 41 00:02:00,400 --> 00:02:01,960 只有做到这点之后 42 00:02:02,000 --> 00:02:06,280 我这里程序才可以去搬它 43 00:02:06,320 --> 00:02:09,760 当然这种搬也是有开销的 44 00:02:09,800 --> 00:02:13,760 你不可以正在处于运行的状态去搬 45 00:02:13,800 --> 00:02:15,640 通常情况下我们会在什么情况去搬 46 00:02:15,680 --> 00:02:19,520 正常情况下 处于等待状态进程 47 00:02:19,560 --> 00:02:22,080 我会对它进行搬动 48 00:02:22,120 --> 00:02:23,520 然后再有一个 49 00:02:23,560 --> 00:02:26,720 并不是说为了一小块区域 50 00:02:26,760 --> 00:02:29,160 我要把整个内存当中的 51 00:02:29,200 --> 00:02:31,880 很多进程都把它挪一遍 52 00:02:31,920 --> 00:02:33,280 这个开销也是大的 53 00:02:33,320 --> 00:02:35,080 我在这里头在什么情况下 54 00:02:35,120 --> 00:02:36,560 我需要考虑到开销 55 00:02:36,600 --> 00:02:39,640 然后进行这种紧凑 56 00:02:39,680 --> 00:02:41,760 关于具体的做法 57 00:02:41,800 --> 00:02:45,280 在大家需要相应的技术的时候 58 00:02:45,320 --> 00:02:46,640 再仔细去看 59 00:02:46,680 --> 00:02:50,160 我们在这就介绍到这种程度 60 00:02:50,200 --> 00:02:52,520 第二种做法是分区对换 61 00:02:52,560 --> 00:02:55,560 刚才我把内存里的这些分区 62 00:02:55,600 --> 00:02:56,840 不管怎么挪 63 00:02:56,880 --> 00:02:59,040 最后的结果它都是在内存里头 64 00:02:59,080 --> 00:03:00,760 如果说这个时候仍然不能用 65 00:03:00,800 --> 00:03:02,320 你还是没办法 66 00:03:02,360 --> 00:03:05,240 所以在这里 内存分区对换 67 00:03:05,280 --> 00:03:10,360 是指我把这种处于等待状态进程 68 00:03:10,400 --> 00:03:12,840 它占用地址空间给它抢占了 69 00:03:12,880 --> 00:03:17,600 然后把这个等待进程占用的数据 70 00:03:17,640 --> 00:03:18,960 我总得找个地方存 71 00:03:19,000 --> 00:03:20,800 我把它存到外存里头去 72 00:03:20,840 --> 00:03:23,760 在这里就是对换到对换区 73 00:03:23,800 --> 00:03:26,360 这时候我内存里的空间也就变大了 74 00:03:26,400 --> 00:03:29,640 在这 我们也通过一个图示来看 75 00:03:29,680 --> 00:03:30,720 在这个图示里 76 00:03:30,760 --> 00:03:33,200 底下是内存和外存的状态 77 00:03:33,240 --> 00:03:35,800 中间这个图实际上说的是 78 00:03:35,840 --> 00:03:37,600 我们在系统里头 79 00:03:37,640 --> 00:03:39,280 进程在执行过程当中 80 00:03:39,320 --> 00:03:42,040 我们维护进程的状态信息 81 00:03:42,080 --> 00:03:45,360 这个我们在后面讨论还会再说到 82 00:03:45,400 --> 00:03:48,000 我们看每创建一个进程 83 00:03:48,040 --> 00:03:51,840 创建的时候它在内存里要占一块区域 84 00:03:51,880 --> 00:03:54,320 创建好之后 它数据结构都弄好 85 00:03:54,360 --> 00:03:56,760 操作系统维护的数据建好 86 00:03:56,800 --> 00:03:59,560 然后这个时候它可以投入到运行状态 87 00:03:59,600 --> 00:04:01,160 它在运行的过程当中 88 00:04:01,200 --> 00:04:03,680 可能会有另外一个进程要创建 89 00:04:03,720 --> 00:04:07,520 它也需要在这里分配相应的存储区域 90 00:04:07,560 --> 00:04:10,320 然后进到就绪状态 91 00:04:10,360 --> 00:04:12,880 第一个还在继续运行 92 00:04:12,920 --> 00:04:15,200 在这个过程当中我们继续可以进行下去 93 00:04:15,240 --> 00:04:18,920 由于某种原因我P1处于等待状态 94 00:04:18,960 --> 00:04:22,240 这个时候P2 P3又进内存里 95 00:04:22,280 --> 00:04:23,640 来运行状态 96 00:04:23,680 --> 00:04:24,880 那么在这种状态下 97 00:04:24,920 --> 00:04:26,360 如果说我再有一个P4进来 98 00:04:26,400 --> 00:04:29,600 它要的空间就不够了 99 00:04:29,640 --> 00:04:30,960 这个时候怎么办呢 100 00:04:31,000 --> 00:04:34,440 我们会把处于等待状这个搬到外存里头去 101 00:04:34,480 --> 00:04:36,160 这样空出一块区域来 102 00:04:36,200 --> 00:04:38,280 我把这个P4放在这里 103 00:04:38,320 --> 00:04:44,360 这是我们就可以让它更多进程在系统里交替运行 104 00:04:44,400 --> 00:04:47,600 使得我的可用空间能变大 105 00:04:47,640 --> 00:04:49,320 在这里大家可以注意到 106 00:04:49,360 --> 00:04:52,440 我们这有一个对换的名字 107 00:04:52,480 --> 00:04:53,760 实际上大家如果注意的话 108 00:04:53,800 --> 00:04:57,280 在你的Linux或者Unix系统里 109 00:04:57,320 --> 00:04:59,640 它有一个分区 叫换区 110 00:04:59,680 --> 00:05:03,440 实际上这个对换区在早期的时候 111 00:05:03,480 --> 00:05:07,400 它就是一种充分利用内存的做法 112 00:05:07,440 --> 00:05:09,360 那么在这张图里头我们可以看到 113 00:05:09,400 --> 00:05:12,400 在早的时候 甚至在操作系统里头 114 00:05:12,440 --> 00:05:15,240 只有一个应用进程可以在内存的状态下 115 00:05:15,280 --> 00:05:19,080 它都可以用对换来实现多进程交替运行 116 00:05:19,120 --> 00:05:20,400 在这是这样的 117 00:05:20,440 --> 00:05:24,360 任何一个时候只有一个进程在内存当中运行 118 00:05:24,400 --> 00:05:27,680 而处于暂停的 是把它放到外存里头 119 00:05:27,720 --> 00:05:32,000 如果说当前进程主动让出处理机使用权限 120 00:05:32,040 --> 00:05:35,400 这个时候做法 把它对换到外存当中 121 00:05:35,440 --> 00:05:38,080 在把外存当中这个搬回去 122 00:05:38,120 --> 00:05:41,840 这个时候我就可以继续运行下去了 123 00:05:41,880 --> 00:05:44,320 用这种办法实际上在我们比较早的时候 124 00:05:44,360 --> 00:05:46,080 内存很紧张的情况下 125 00:05:46,120 --> 00:05:48,560 我们在系统里就可以实现 126 00:05:48,600 --> 00:05:51,240 多进程的交替运行 127 00:05:51,280 --> 00:05:53,200 当然在这里这个交替 128 00:05:53,240 --> 00:05:54,440 它的开销是非常大的 129 00:05:54,480 --> 00:05:58,760 原因在于内存和外存之间的速度差的很远 130 00:05:58,800 --> 00:06:01,600 即使是这样 由于我们前面的系统 131 00:06:01,640 --> 00:06:04,000 计算机系统它的成本非常高 132 00:06:04,040 --> 00:06:07,320 所以这样做的开销 也是可以接受的 133 00:06:07,360 --> 00:06:09,360 当然在这里头我在对换的时候 134 00:06:09,400 --> 00:06:10,720 到底把谁对换出来 135 00:06:10,760 --> 00:06:12,400 这个时候开销有多大 136 00:06:12,440 --> 00:06:13,680 这个时候在系统里 137 00:06:13,720 --> 00:06:15,160 你就得经过仔细的权衡 138 00:06:15,200 --> 00:06:17,120 所以在前面做的时候 139 00:06:17,160 --> 00:06:18,840 它花很大的精力会去解决 140 00:06:18,880 --> 00:06:23,160 我到底是对换哪一个进程 141 00:06:23,200 --> 00:06:25,400 这是我们在早期的时候 142 00:06:25,440 --> 00:06:27,280 计算机系统里的多进程 143 00:06:27,320 --> 00:06:29,760 通过对换区的方式来做的一种实现 144 00:06:29,800 --> 00:06:29,840