malloc返回内存或虚拟地址空间

时间:2011-04-20 09:18:54

标签: c windows linux memory

malloc是否在堆上分配了一块内存,还是应该称为虚拟地址空间?

我是否挑剔称它为虚拟地址空间或者这只是DOS的遗产? Linux怎么样?

编辑:

许多答案都有很多细节,但没有一个能回答我的问题。

15 个答案:

答案 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堆栈的动态分配   而不是堆(例如Unix   alloca(),Microsoft Windows CRTL   malloca())。这个记忆是   通话时自动释放   功能结束。对此的需求是   减少了C99的变化   标准,增加了支持   块范围的可变长度数组   在运行时确定尺寸。

如果您对术语的含义感到困惑,那么Wikipedia articleheap memory上的维基百科文章可能会对您有所帮助。

答案 7 :(得分:1)

要回答这个问题,我们需要知道我们正在处理什么样的操作系统和架构。正如pmg提到的标准和文章指的是“存储”或“空间”。除非我们做出一系列假设,否则这些是最通用的术语和唯一有效的术语。

例如:

  

malloc分配一个Virtual块   堆上的地址空间

这对许多嵌入式系统来说都不正确。他们中的许多人不使用虚拟内存,因为没有必要(没有多任务处理等)或出于性能原因。更有甚者,一些奇特的设备可能没有堆的想法 - 怀疑会使用malloc,但公平地说这是标准引用“存储”的原因之一 - 它是特定于实现的。

另一方面,这个例子适用于我们PC中的Window和Linux。让我们分析它来回答这个问题。

首先,我们需要定义什么是虚拟地址空间。

虚拟地址空间(VAS)是一种内存映射机制,可帮助管理多个进程。

  • 隔离进程 - 每个进程都有 他自己的地址空间
  • 允许分配32位的内存 建筑仅限于。
  • 提供了一个简洁的记忆模型

回到问题,“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)都支持mallocthe heapvirtual memory

答案 12 :(得分:0)

malloc()专门从堆中分配。

堆内存是否在虚拟地址空间中完全取决于操作系统和硬件架构。在具有MMU和使用它的操作系统的系统上,所有内存(堆,代码空间,堆栈,静态内存和内存映射I / O等)存在于虚拟空间中,甚至如果物理到虚拟映射是一对一的。

要拥有虚拟地址空间需要MMU将物理地址映射到虚拟地址,并非所有目标都有MMU,因此堆内存和虚拟内存不是任何方式的同义或可互换概念;它们完全是独立的概念。

关于“虚拟地址空间”是“DOS的遗产”,你无法进一步说实话,16位x86架构根本不支持MMU或虚拟内存。我想知道你是怎么想到的?

答案 13 :(得分:0)

malloc()分配由进程拥有的虚拟内存。

在执行过程中,操作系统可以多次将该过程重新加载到物理内存中。操作系统将每个进程的虚拟地址映射到物理内存。进程不知道映射。

虚拟地址空间空间由

组成
  • 系统空间(驱动程序)和
  • 用户空间(一个程序代码区域,一个用于动态内存分配,一个 stack 用于变量,参数,返回值等)

答案 14 :(得分:-1)

内核和用户空间使用由内存管理硬件映射到物理地址的虚拟地址(也称为线性地址)。 此映射由页面表定义,由操作系统设置。

点击Memory Allocation上的此链接。