RAM是如何分配的? [关闭]

Posted

技术标签:

【中文标题】RAM是如何分配的? [关闭]【英文标题】:How is RAM allocated? [closed] 【发布时间】:2014-03-15 02:53:01 【问题描述】:

这是一个关于计算机科学的菜鸟问题:ram 是如何分配的?

例如,我使用 Windows。我可以知道程序使用了哪些地址吗? Windows如何分配内存?连续的还是不连续的? 在 Linux 操作系统上也一样吗?

而且,我可以通过程序访问整个内存吗? (我不相信,但是...)

你知道这方面有什么好的讲座/文档吗?

【问题讨论】:

你可以搜索“分页”和“虚拟内存” 参见this answer 专注于 Linux。 感谢您的回答:) @NiklasB。不要认为它太宽泛。我可以想象一个新的程序员或爱好者会从这个问题中获得很多。你看,对于“简单”的问题,确实没有多少离散的答案,但这些都一样重要。 @simon 我们这里已经有了不错的答案 【参考方案1】:

首先,当你认为你正在分配 RAM,你真的不是。我知道这很令人困惑,但是一旦您了解了它的工作原理,它实际上并不复杂。继续阅读。

RAM 由操作系统以称为“页”的单位分配。通常,这意味着 4kiB 的连续区域,但其他大小也是可能的(更复杂的是,在现代处理器上存在对“大页面”(通常为 1-4MiB 的数量级)的支持,并且操作系统可能具有分配粒度与页面大小不同,例如 Windows 的页面大小为 4kiB,粒度为 64kiB)。 让我们忽略那些额外的细节,只考虑具有特定大小 (4KiB) 的“页面”。

如果您分配和使用的区域大于系统的页面大小,您通常会没有拥有连续的内存,但您仍然会看到它是连续的,因为您的程序只能在虚拟地址中“思考”。实际上,您可能正在使用两个(或更多)根本不连续的页面,但它们似乎是。这些虚拟地址由 MMU 透明地转换为实际地址。 此外,并非您认为已分配的所有内存都必须始终存在于 RAM 中,并且相同的虚拟地址可能在不同时间对应于完全不同的 RAM 块(例如,当页面被换出并随后再次换入时) -- 你的程序会在同一个地址看到它,但实际上它很可能在不同的 RAM 中)。

虚拟内存是一种非常强大的工具。虽然您程序中的一个地址只能引用 RAM 中的 [最多] 一个物理地址(在特定页面中),但 RAM 的一个物理页面可以映射到您程序中的几个不同地址,并且甚至在几个独立的程序中。 例如,可以创建“循环”内存区域,并且来自共享库的代码通常被加载到 一个 内存位置,但同时被 许多 程序使用(并且它将在这些不同的程序中具有不同的地址)。或者,您可以使用该技术在程序之间共享内存,这样当一个程序写入某个地址时,另一个程序的内存位置中的值会发生变化(因为它是完全相同的内存!)。

在高层次上,您向标准库请求内存(例如malloc),标准库以或多或少未指定的方式管理它保留的区域池(有许多不同的分配器实现,它们都有一个共同点,您可以向它们请求内存,然后它们会返回一个地址 - 这是您认为您在分配 RAM 而实际上不是的地方)。 当分配器需要更多内存时,它会要求操作系统保留另一个块。在 Linux 下,这可能是 sbrkmmap,在 Windows 下,这可能是 VirtualAlloc

一般来说,你可以用内存做 3 件事,它在 Linux 和 Windows(以及所有其他现代操作系统)下的工作原理大致相同,尽管使用的 API 函数不同,并且还有一些细微的差异。

您可以保留它,这或多或少没有任何作用,除了在逻辑上划分您的地址空间(只有您的进程关心)。 接下来,您可以提交它,这同样没有多大作用,但它会在一定程度上影响其他进程。系统对它可以为所有进程(物理 RAM 加上页面文件大小)提交多少内存有一个总限制,并且它会跟踪它。这意味着您提交的内存与另一个进程可能提交的限制相同。否则,同样不会发生太多事情。 最后,您可以访问内存。最后,这具有显着的效果。在第一次访问页面时,会发生错误(因为该页面根本不存在!),操作系统要么从文件中获取一些数据(如果页面属于映射),要么清除一些页面(可能在第一次将其保存到磁盘)。然后,操作系统会调整虚拟内存系统中的结构,以便您在访问的地址处看到这个 RAM 的物理页面。

在您看来,这些都是不可见的。它就像魔术一样工作。

可以检查进程在其地址空间中的哪些区域被使用,并且可以(但有点无意义)将其转换为物理地址。请注意,在不同时间运行的同一程序可能会存储例如不同地址的一个特定变量。例如,在 Windows 下,您可以使用VMMap 工具检查进程内存分配。

如果您编写自己的操作系统,则只能使用所有 RAM,因为操作系统保留的内存总是很少,用户进程无法使用。 否则,您原则上可以使用[几乎]所有内存。但是,您是否可以直接使用那么多取决于您的进程是 32 位还是 64 位。现在的计算机通常具有比 32 位寻址更多的 RAM,因此您需要使用地址窗口扩展或者您的进程必须是 64 位。此外,即使给定的 RAM 量原则上可使用 32 位寻址,某些地址空间因素(例如碎片化、内核保留)可能会阻止您直接使用所有内存。

【讨论】:

Damon,非常感谢您的完整回答。记忆似乎是一件困难的事情,但我对此很感兴趣......

以上是关于RAM是如何分配的? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如果我的操作系统使用连续内存分配模型,我可以在4GB RAM上运行5GB进程[关闭]

C ++读/写 - RamDisk vs RAM [关闭]

SQL Server 实际使用了多少 RAM? [关闭]

内存段和物理 RAM [关闭]

允许的内存大小为 134217728 字节已用尽(尝试分配 42 字节)[关闭]

使用 QlistW 减少 RAM 使用 [关闭]