malloc是否在堆上分配了一块内存,还是应该称为虚拟地址空间?
我是否挑剔称它为虚拟地址空间或者这只是DOS的遗产? Linux怎么样?
编辑:
许多答案都有很多细节,但没有一个能回答我的问题。
答案 0 :(得分:8)
malloc
在堆上分配内存,句点。
您的C库通常会保留可用内存块的列表(或更复杂的数据结构),找到一个合适的块以满足malloc
(可能将更大的块拆分为多个较小的块)并返回列表中的free
'内存(可能将一些较小的块合并为一个较大的块)
仅当列表中没有足够大的块来满足您的malloc
时,库会要求操作系统提供更多内存,例如:使用sbrk系统调用。此系统调用返回的地址可能是虚拟地址,也可能是真实地址,具体取决于您的硬件,但作为程序员,您不能(也不需要)知道这一点。
说malloc
分配虚拟地址空间而不是堆上的块就像是说read
从硬盘读取而不是从文件中读取:它与调用者的角度无关,并且并非总是如此。
答案 1 :(得分:6)
至少有3种测量内存消耗的方法:
malloc
通常会影响所有人。
编辑:所以,我能想到回答你问题的最佳方式就是说:
malloc
分配虚拟内存。
虚拟内存消耗:
答案 2 :(得分:4)
malloc是否在堆上分配了一块内存,还是应该称为虚拟地址空间?
简短回答:malloc在堆上分配内存。
它不是足够精确来表示malloc在虚拟地址[sic]空间中分配内存,因为你的调用堆栈本身就是同一空间的一部分。
答案 3 :(得分:4)
malloc
是一个图书馆电话。在linux上,它又调用sbrk
系统调用。 sbrk
将增加堆的大小,但实际上并不分配物理内存。当进程尝试访问此地址时,会引发page fault
,然后内核会分配实际的物理页面并映射到虚拟地址。
TL; DR:malloc
返回虚拟地址,不分配物理内存。
检查this。
答案 4 :(得分:2)
malloc()
会在HEAP上分配一块内存。
它应该被称为虚拟地址空间吗?坚持这一想法一秒钟。 VAS (虚拟地址空间)是一种内存映射机制,包含应用程序的整个内存空间。换句话说,VAS不限于HEAP的存储区域。 HEAP实际上只是其中的另一部分。
每次运行新应用程序时,操作系统都会创建一个新进程并为该应用程序分配新的VAS。通过malloc()
分配的内存在HEAP上保留,HEAP是VAS中的一个特殊内存区域,如您所知,通过标准方式分配的内存最终在堆栈中,这是位于VAS内部的另一个内存区域申请书。
答案 5 :(得分:1)
所有进程都在自己的虚拟地址空间内运行。每次访问内存都由内存管理单元调解。如果映射了内存,则从相应的物理地址加载或存储数据。如果没有内存映射到指定的地址,(内存管理单元(MMU)将触发异常。
Malloc管理一堆(或者甚至只是一小部分)映射的内存页面。这些页面称为堆。当一个人从malloc请求多个字节时,malloc将在它已经管理的页面中找到该内存,或者它会询问操作系统(在linux上使用brk或mmap)。这对malloc的用户完全透明。
所以这两个概念是完全正交的。进程访问虚拟内存,MMU可以将其转换为物理地址,堆是malloc管理的内存块。
答案 6 :(得分:1)
如果你对RTFM感到困扰,你本可以自己回答这个问题: - )
特别是,在Linux机器上键入man malloc
并一次一个地搜索“堆”和“虚拟”将让您明确地看到malloc()
是用术语定义的堆内存,而不是虚拟内存。
malloc()
的{{3}}与Linux手册页一致。它指出(重点是我的):
在C中,库函数
malloc
是 用来分配一块内存 堆。 [...]有些平台提供 允许运行时的库调用 来自C堆栈的动态分配 而不是堆(例如Unixalloca()
,Microsoft Windows CRTLmalloca()
)。这个记忆是 通话时自动释放 功能结束。对此的需求是 减少了C99的变化 标准,增加了支持 块范围的可变长度数组 在运行时确定尺寸。
如果您对术语的含义感到困惑,那么Wikipedia article和heap memory上的维基百科文章可能会对您有所帮助。
答案 7 :(得分:1)
要回答这个问题,我们需要知道我们正在处理什么样的操作系统和架构。正如pmg提到的标准和文章指的是“存储”或“空间”。除非我们做出一系列假设,否则这些是最通用的术语和唯一有效的术语。
例如:
malloc分配一个Virtual块 堆上的地址空间
这对许多嵌入式系统来说都不正确。他们中的许多人不使用虚拟内存,因为没有必要(没有多任务处理等)或出于性能原因。更有甚者,一些奇特的设备可能没有堆的想法 - 怀疑会使用malloc,但公平地说这是标准引用“存储”的原因之一 - 它是特定于实现的。
另一方面,这个例子适用于我们PC中的Window和Linux。让我们分析它来回答这个问题。
首先,我们需要定义什么是虚拟地址空间。
虚拟地址空间(VAS)是一种内存映射机制,可帮助管理多个进程。
回到问题,“malloc是否在堆上分配了一块内存,还是应该称为Virtual Adress Space?”
两种陈述都是正确的。我宁愿说VAP而不是内存 - 它更明确。有一个常见的神话,即malloc = RAM内存。回到过去,DOS内存分配非常简单。每当我们要求记忆时,它总是RAM,但在现代的Oses中,它可能会有所不同。
答案 8 :(得分:1)
Malloc总是返回虚拟地址,原因是当你调用malloc它实际上是一个调用系统调用的包装函数(系统调用是内核级指令的一个奇特的词),这个系统调用在你的内部分配一个虚拟内存堆段。但是当你想访问分配的值(存储或加载指令)时,MMU会引发Page fault,这基本上意味着这个虚拟页面没有物理内存,只有那时OS才会为这个虚拟页面分配物理内存。
答案 9 :(得分:0)
malloc
在堆上分配一个块。对于分配的块跨越的每个存储器页面,可能会或可能不会在开始时向其提交物理存储器。但整个块都可以使用,因为操作系统将负责处理页面错误并管理支持分配所需的物理/虚拟内存。
答案 10 :(得分:0)
答案取决于底层操作系统,libc实现和硬件架构。对于在x86架构上运行的大多数现代操作系统(如Linux或Windows),您将在线性地址空间中获得指针,但通常这取决于实现。我怀疑,例如,当用C编程一些小型设备(如微控制器)时,malloc()会返回一个指向虚拟内存的指针,因为没有虚拟内存。
答案 11 :(得分:0)
Malloc在堆上分配,这是虚拟地址空间的一部分。
你称之为虚拟地址空间并不挑剔,你只是过于笼统。可以比较说,“你在浴室里呕吐。”严格来说这是真的,但“你在锅里呕吐”更准确,因为前一种说法暗示你也可以在水槽或浴缸里呕吐。
从概念上讲,大多数操作系统(包括Dos和Linux)都支持malloc,the heap和virtual memory。
答案 12 :(得分:0)
malloc()
专门从堆中分配。
堆内存是否在虚拟地址空间中完全取决于操作系统和硬件架构。在具有MMU和使用它的操作系统的系统上,所有内存(堆,代码空间,堆栈,静态内存和内存映射I / O等)存在于虚拟空间中,甚至如果物理到虚拟映射是一对一的。
要拥有虚拟地址空间需要MMU将物理地址映射到虚拟地址,并非所有目标都有MMU,因此堆内存和虚拟内存不是任何方式的同义或可互换概念;它们完全是独立的概念。
关于“虚拟地址空间”是“DOS的遗产”,你无法进一步说实话,16位x86架构根本不支持MMU或虚拟内存。我想知道你是怎么想到的?
答案 13 :(得分:0)
malloc()
分配由进程拥有的虚拟内存。
在执行过程中,操作系统可以多次将该过程重新加载到物理内存中。操作系统将每个进程的虚拟地址映射到物理内存。进程不知道映射。
虚拟地址空间空间由
组成答案 14 :(得分:-1)
内核和用户空间使用由内存管理硬件映射到物理地址的虚拟地址(也称为线性地址)。 此映射由页面表定义,由操作系统设置。
点击Memory Allocation上的此链接。