<分区>
我有点困惑。在操作系统类(class)中,我们被告知所有操作系统都通过分页或分段处理内存碎片,并且根本没有连续的物理内存分配。操作系统使用不同级别的寻址(逻辑/物理)来避免连续的内存分配。现在here有很多关于它的讨论。我的问题是: 这个问题在支持逻辑寻址的操作系统的 C++ 编程中是否真实存在(是否有任何进程仅因为内存碎片而崩溃)?如果是,为什么首先每个操作系统都试图避免连续寻址?
<分区>
我有点困惑。在操作系统类(class)中,我们被告知所有操作系统都通过分页或分段处理内存碎片,并且根本没有连续的物理内存分配。操作系统使用不同级别的寻址(逻辑/物理)来避免连续的内存分配。现在here有很多关于它的讨论。我的问题是: 这个问题在支持逻辑寻址的操作系统的 C++ 编程中是否真实存在(是否有任何进程仅因为内存碎片而崩溃)?如果是,为什么首先每个操作系统都试图避免连续寻址?
最佳答案
有两层:虚拟进程地址空间中的碎片和物理内存中的碎片。
如果您查看任何现代应用程序,您会发现它的内存使用量是如何随着时间的推移而增长的,因为内存没有释放给操作系统。您可以说这是由其他原因引起的,但内存碎片(例如,分配的内存块的位置不连续)是造成这种情况的核心原因。简而言之,内存分配器拒绝向操作系统释放内存。
如果您对物理内存中的碎片感兴趣,那么即使内存按页组织,仍然需要分配物理上连续的内存块。例如,如果您需要避免虚拟内存开销,您可能希望使用大页面(Linux 中的“大页面”)。 x86_64 支持 4KiB、2MiB 和 1GiB 页面。如果没有所需大小的连续物理内存,您将无法使用它们。
如果操作系统是指“内核”,那么它无法帮助您处理进程地址空间中发生的碎片(堆碎片)。 C 库应该尽量避免碎片化,不幸的是,它并不总是能够这样做。查看链接 question .
内存分配器通常无法释放大块内存,如果其中至少有一些分配的话。有一个部分解决方案利用页面中的虚拟内存组织 - 所谓的“无惰性”机制,由 MADV_FREE
表示在 Linux 和 BSD 上以及 DiscardVirtualMemory
在 Windows 上。当你有一大块内存只被部分使用时,你可以通知内核那部分内存不再需要了,它可以在内存压力下收回它。这是延迟完成的,并且仅在内存压力下完成,因为内存释放非常昂贵。但是出于性能原因,许多内存分配器仍然不使用它。
所以您问题的答案 - 这取决于您对程序效率的关注程度。大多数程序并不关心,因为标准分配器只是为它们完成工作。当标准分配器无法有效地完成其工作时,某些程序可能会受到影响。
关于c++ - "Memory Fragmentation"这还是个问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52018123/