在 32 位机器中,每个进程获得 4GB 的虚拟空间。在这种情况下,人们可能会担心我们可能会因碎片化而面临麻烦。但是在 64 位机器的情况下,理论上我们有一个巨大的可寻址虚拟内存,那么为什么在 64 位机器中内存碎片仍然是一个问题(如果是的话)?
2 回答
您尝试访问的每个虚拟地址都由操作系统映射到物理内存。物理内存按页分配(例如 4K 大小)。如果您设法在偏移量 1000000*n 处分配一个字节并将 n 从 1 分配到 1000000 (我认为您可以使用 mmap 做到这一点),那么操作系统将不得不使用一百万页物理内存来支持它,即4G之类的。该物理内存将无法用于其他任何事情。如果您连续分配字节,则百万字节只需要大约 1M 的物理内存(256 页)。
如果您出于正当理由分配 4G,然后释放其中的一部分,保留每个分配的页面的一部分,您可能会遇到类似的糟糕情况。操作系统将无法实际将释放的内存重新用于其他任何事情,因为没有完全空闲的物理页面。所以这是一个碎片问题。
理论上,您可以想象虚拟地址 1000000 和 2000000 将映射到物理内存的同一页,从而避免了碎片。但实际上,出于充分的理由,虚拟内存映射是逐页完成的。您可以在此处阅读更多相关信息:http ://en.wikipedia.org/wiki/Page_table 。
因为所有这些内存都被“浪费”了,所以考虑一个存在大量内部碎片的应用程序。该过程需要更多内存页面,因为工作集现在分散在内存中,这意味着它的内存占用要高得多。如果此应用程序正在争夺 RAM 中的物理插槽(对于典型的家庭设置,机器实际上仍然只有大约 4 - 8 GB 的 RAM),那么它会导致更多的页面交换。通常,您希望减少应用程序的内存占用,以避免内存压力和与其他应用程序的争用。
在某些情况下,虽然它并不重要,但在这里或那里使用额外的兆字节不会杀死你,但在更大的应用程序中这一切都会加起来。这取决于情况,是否尽可能少的碎片很重要,具体取决于您正在编码的内容或项目的目标是什么。