我在an article about malloc中看到了以下段落。
堆是连续的(在虚拟地址方面)空间 具有三个边界的内存:起点,最大限制(托管 通过sys / ressource.h的函数getrlimit(2)和setrlimit(2))和 一个叫做休息的终点。中断标记映射的结束 内存空间,即虚拟地址空间的一部分 与真实记忆的对应。
我想更好地理解映射区域和未映射区域的概念。
答案 0 :(得分:11)
如果内存地址长度为64位,就像在许多现代计算机中一样,您有18446744073709551616个可能的内存地址。 (这取决于处理器架构实际可以使用多少位,但地址使用64位存储。)这超过170亿千兆字节,这可能比计算机实际拥有的内存更多。因此,这170亿千兆字节中只有一部分对应于实际内存。对于其余地址,内存根本不存在。存储器地址和存储器位置之间没有对应关系。因此,这些地址未映射。
这是一个简单的解释。实际上,它有点复杂。程序的内存地址不是计算机中内存芯片的实际内存地址,即物理内存。相反,它是虚拟内存。每个进程都有自己的内存空间,即自己的18446744073709551616地址,进程使用的内存地址由计算机硬件转换为物理内存地址。因此,一个进程可能已经将一些数据存储在存储器地址4711处,其实际上存储在这里的实际物理存储器芯片中,并且另一个进程可能还将一些数据存储在存储器地址4711处,但这是一个完全不同的地方,存储在那里的真实物理内存芯片中。进程内部虚拟内存地址被转换或映射到实际物理内存,但不是全部。其余的,未映射。
当然,这也是 的简化说明。您可以使用比计算机中物理内存量更多的虚拟内存。这是通过 paging 来完成的,也就是说,取出一些现在没有使用的内存块(称为 pages ),并将它们存储在磁盘上,直到再次需要它们为止。 (这也称为"交换",即使该术语最初意味着将所有进程的内存写入磁盘,而不仅仅是部分内容。)
进一步使其复杂化,现代操作系统(如Linux和Windows )在分配内存时会过度使用。这意味着即使使用磁盘,它们也会分配比存储在计算机上的内存地址更多的内存地址。例如,我的计算机具有32千兆字节的物理内存,只有4千兆字节可用于将数据分页到磁盘,但可能不允许超过36千兆字节的实际可用虚拟内存。但malloc很乐意分配超过一百千千兆字节。直到我真正尝试将内容存储在连接到物理内存或磁盘的所有内存中。但它是我的虚拟内存空间的一部分,所以我也称之为映射内存,即使它没有映射到任何东西。
答案 1 :(得分:1)
堆中的映射区域表示可以与物理内存一起映射的虚拟内存区域。未映射的区域表示未使用的虚拟内存空间,它不指向任何物理内存。
堆的映射区域和未映射区域之间的边界是系统断点。由于malloc()
用于请求一些内存,系统断点将被移动以放大映射区域。 Linux系统提供brk()
和sbrk()
方法来增加和减少系统断点的虚拟内存地址。