分页怎么有内部碎片没有外部碎片?

Posted

技术标签:

【中文标题】分页怎么有内部碎片没有外部碎片?【英文标题】:How is there internal fragmentation in paging and no external fragmentation? 【发布时间】:2015-12-21 01:43:04 【问题描述】:

请好好解释一下。不要只写定义。还要解释它的作用以及它与分段有何不同。

【问题讨论】:

【参考方案1】:

内存分配技术需要考虑碎片化。分页基本上不是一种内存分配技术,而是一种提供虚拟地址空间的方法。

考虑到与分段的比较,您可能要问的是使用固定大小块的内存分配技术(如分页的页面,此处假设页面大小为 4KB)与使用可变大小块的技术(如用于分割的段)。

现在,假设你直接使用页面分配接口来实现内存管理,即你有两个处理内存的函数:

alloc_page,它分配一个单独的页面并返回一个指向新可用地址空间开头的指针,并且 free_page,释放一个已分配的页面。

现在假设您所有当前可用的虚拟内存都已使用,但您需要额外存储 1 个字节。您调用alloc_page 并获得一个4KB 的内存块。你只使用了那个大块的 1 个字节,但从分配器的角度来看,其他 4095 个字节也被使用了。如果这种情况多次发生,最终所有页面都将被分配,因此对alloc_page 的进一步调用将失败。即使您只需要另一个额外的字节(可能是上面浪费的 4095 字节之一),分配器也会告诉您内存不足。这是内部碎片。

另一方面,如果您使用可变大小的块(如分段),那么您很容易受到外部碎片的影响:假设您管理 6 字节的内存(F 表示“免费”):

FFFFFF

首先为a分配3个字节,然后为b分配1个字节,最后为c分配2个字节:

aaabcc

现在你释放ac,只留下b 分配:

FFFbFF

您现在有 5 字节的未使用内存,但如果您尝试分配一个 4 字节的块(小于可用内存),则分配将由于b 的内存位置不利而失败。这是外部碎片。

现在,如果您将页面分配器扩展为能够分配多个页面并添加alloc_multiple_pages,您必须同时处理内部外部碎片。

【讨论】:

【参考方案2】:

分页没有外部碎片,但存在内部碎片。 首先,我们需要了解什么是外部碎片。当我们有一个内存来容纳一个进程但它不是连续的时,就会发生外部碎片。 怎么不会出现在分页中? 分页将虚拟内存或所有进程划分为大小相等的页面,将物理内存划分为固定大小的帧。因此,您通常会将称为页面的相同大小的块固定到称为框架的相同块状空间中!尝试想象并得出结论,永远不会有外部碎片。

在分段的情况下,我们将虚拟地址划分为不同大小的块,这就是为什么主内存中的某些块必须粘在一起或紧凑以便为新进程腾出空间的原因!希望对你有帮助!

【讨论】:

【参考方案3】:

分页允许以非连续方式为进程分配物理内存。我会回答为什么在分页中不会出现外部碎片。

当分配了连续内存的进程从物理内存中卸载时会发生外部碎片,这会在内存中创建一个空洞(空闲空间)。

现在如果有一个新进程出现,它需要比这个漏洞更多的内存,那么由于非连续,我们将无法为该进程分配连续内存空闲内存的性质,这称为外部碎片。

现在,上述问题源于为进程分配连续内存的限制。这就是分页通过允许进程获取非连续物理内存来解决的问题。

【讨论】:

【参考方案4】:

当一个进程被分成固定大小的页面时,最后一页通常会有一些剩余空间(内部碎片)。当有许多进程时,它们最后一页的未使用区域加起来可能大于或等于一页的大小。现在,即使您必须拥有一页或更多的总可用大小,但您无法加载新页面,因为页面必须是连续的。外部碎片已经发生。所以,我不认为外部碎片在分页中完全为零。

编辑:这完全是关于如何定义外部碎片。内部碎片的收集对外部碎片没有贡献。 外部碎片是由分区(或页面)的EXTERNAL空白空间造成的。因此,如果假设主存中只有两帧,例如大小为 16B,每帧仅占用 1B 数据。每帧的内部碎片为15B。总未使用空间为 30B。现在,如果您想加载某个进程的一个新页面,您将看到您没有任何可用的框架。即使您有 30B 的未使用空间,您也无法加载新页面。你会称之为外部碎片吗?答案是否定的。因为这些 15B 未使用的空间是页面的内部空间。所以在分页中,内部碎片是可能的,但外部碎片是不可能的。

【讨论】:

感谢 Ayush 的回答。我来自 BIET Jhansi :)【参考方案5】:

在分页中,虽然可能会出现内部碎片,但出现外部碎片的概率非常低。

在分页方案中,整个主内存和虚拟内存被划分为一些固定大小的槽,这些槽称为页(在虚拟内存的情况下)和页框(在主内存或RAM或物理内存的情况下)。因此,每当一个进程在主存中执行时,它就占据了一个页框的整个空间。让我们说,主存储器有 4096 个页框,每个页框的大小为 4096 字节。假设有一个进程 P1 需要 3000 字节的空间在主存中执行。因此,为了执行 P1,它被从虚拟内存带到主内存并放置在页框 (F1) 中,但 P1 只需要 3000 字节的空间来执行它,因此 (4096 - 3000 = 1096 字节) 页框 F1 中的空间被浪费了。换句话说,这表示页面框架 F1 内部碎片的情况。

同样,如果主内存的某些空间不能包含在页框中,则可能会出现外部碎片。但这种情况非常罕见,因为通常是主存储器的大小、页框的大小以及总数。主内存中的页框数可以用 2 的幂来表示。

【讨论】:

【参考方案6】:

据我所知,我会这样回答你的问题:

为什么分页会产生内部碎片?

因为页面具有固定大小,但进程可能会请求更多或更少的空间。假设一个页面是 32 个单元,而一个进程请求 20 个单元。然后,当一个页面被提供给请求进程时,尽管有 12 个单位的空闲“内部”空间,该页面不再可用。

为什么没有分页的外部碎片?

因为在分页中,允许进程分配物理内存中不连续的空间。同时,这些块的逻辑表示在虚拟内存中是连续的。这就是我的意思:

一个进程需要 128 个单位的空间。与前面的示例一样,这是 4 页。不管物理内存中的实际页号(正式的帧号)如何,您都可以为这些页指定编号 0、1、2 和 3。这是分页本身的定义特征的虚拟表示。这些页面在实际物理内存中可能是 21、213、23、234。但它们实际上可以是任何东西,连续的或不连续的。因此,即使分页在 used 空间之间留下小的 free 空间,这些小的空闲空间仍然可以一起使用,就好像它们是一个连续的空间块一样。这就是为什么不会发生外部碎片的原因。

【讨论】:

【参考方案7】:

帧被分配为单位。如果一个进程的内存需求与页边界不一致,那么分配的最后一帧可能没有完全填满。

例如,如果页面大小为 2,048 字节,则 72,766 字节的进程将需要 35 个页面加上 1,086 字节。它将被分配 36 帧,从而导致 2,048 - 1,086 = 962 字节的内部碎片。在最坏的情况下,一个进程需要 11 个页面加上 1 个字节。它将被分配 11 + 1 帧,从而导致几乎整个帧的内部碎片。

【讨论】:

这个答案并没有完全解决问题。根本不谈论外部碎片。

以上是关于分页怎么有内部碎片没有外部碎片?的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver索引碎片怎么避免

内存分配方式及内存碎片

外部碎片进程描述符内部碎片

内部和外部碎片[关闭]

内存管理——内部碎片和外部碎片

如何减小内存碎片