【问题标题】:When is it more appropriate to use valloc() as opposed to malloc()?什么时候使用 valloc() 而不是 malloc() 更合适?
【发布时间】:2016-05-31 14:51:15
【问题描述】:

C(和 C++)包含一系列动态内存分配函数,其中大部分函数的命名很直观,并且易于向对内存有基本了解的程序员解释。 malloc() 只是分配内存,而calloc() 分配一些内存并急切地清除它。还有realloc()free(),很不言自明。

malloc() 的手册页还提到了valloc(),它分配 (size) 字节与页面边框对齐

不幸的是,我的背景在低层次的复杂性方面不够透彻;分配和使用与页面边界对齐的内存有什么影响?与常规的malloc()calloc() 相比,这在什么时候合适?

【问题讨论】:

  • MSVC 没有valloc,但有_aligned_malloc
  • 简答:在大多数架构中只是因为性能,但您需要一个特定于实现的功能。
  • 我看不到 valloc 是标准 C,也不是 POSIX。所以你的问题有点没用。如果您需要特定的对齐方式,请使用 aligned_alloc
  • @Olaf 如果您可以对此进行扩展,我相信您的评论可能是一个建设性的答案。

标签: c memory-management malloc


【解决方案1】:

valloc 的联机帮助页包含一个重要说明:

函数 valloc() 出现在 3.0BSD 中。它在 4.3BSD 中被记录为过时,在 SUSv2 中被记录为遗留。它没有出现在 POSIX.1-2001 中。

valloc 已过时且不标准 - 要回答您的问题,它永远不适合在新代码中使用。

虽然有一些原因要分配对齐的内存 - this question 列出了一些好的 - 通常最好让内存分配器找出给你的内存位。如果您确定需要将新分配的内存与某些内容对齐,请改用 aligned_alloc (C11) 或 posix_memalign (POSIX)。

【讨论】:

  • 其他问题中没有提到真正适用于 page 对齐的分配。
  • glibc manual 好奇的还是提到了它,甚至给出了一个实现。
  • @iharob:在最新版本的 Ubuntu Xenial 上,vallocposix_memalign 手册页中进行了讨论,man valloc 将把它拉出来。
  • @NateEldredge OP 声明在malloc() 手册页中提到了它。我现在也在 Ubuntu Xenial 上,但它不存在。但是我看到了混乱,我一定是不小心删除了部分评论并且没有注意到。
【解决方案2】:

进行页面对齐的分配通常不是为了速度 - 它们是因为您想利用处理器 MMU 的某些功能,该功能通常适用于页面粒度。

一个例子是,如果您想使用mprotect(2) 更改对该内存的访问权限。例如,假设您想将一些数据存储在一块内存中,然后将其设为只读,这样您的程序中任何试图在那里写入的错误部分都会触发段错误。由于mprotect(2) 只能逐页更改权限(因为这是底层 CPU 硬件可以强制执行的),所以存储数据的块最好是页面对齐的,并且它的大小最好是页面大小的倍数。否则,您设置为只读的区域可能包含其他仍需要写入的不相关数据。

或者,也许您要在内存中生成一些可执行代码,然后想稍后执行它。您默认分配的内存可能未设置为允许代码执行,因此您必须使用mprotect 为其授予执行权限。同样,这必须通过页面粒度来完成。

另一个例子是如果你现在想分配内存,但以后可能想mmap 一些东西。

因此,一般来说,页面对齐内存的需求与一些相当低级的应用程序有关,通常涉及系统特定的东西。如果你需要它,你会知道的。 (如前所述,您不应使用valloc 分配它,而应使用posix_memalign 或匿名mmap。)

【讨论】:

    【解决方案3】:

    首先valloc已经过时了,应该改用memalign

    第二件事,它根本不是 C (C++) 标准的一部分。

    这是与_SC_PAGESIZE 边界对齐的特殊分配。

    什么时候使用它有用?我想永远不会,除非您有一些特定的低级要求。如果您需要它,您就会知道需要它,因为它很少有用(可能只是在尝试一些微优化或在进程之间创建共享内存时)。

    【讨论】:

      【解决方案4】:

      不言而喻的答案是,当 malloc 不适合(效率较低)应用程序(虚拟)内存使用模式并且 valloc 更适合(更有效)时,使用 valloc 是合适的。这将取决于操作系统和库以及架构和应用程序...

      malloc 传统上从释放的内存中分配实际内存(如果可用),如果不可用则增加 brk 点,在这种情况下,出于安全原因,它会被操作系统清除。

      calloc 在愚蠢的实现中执行 malloc 然后(重新)清除内存,而智能实现将避免重新清除操作系统自动清除的新分配的内存。

      valloc 与虚拟内存有关。在使用文件系统的虚拟内存系统中,您可以分配大量内存或文件空间/交换空间,甚至比物理内存更多,并且它将按页面交换,因此对齐是一个因素。在 Unix 中,创建指定文件的文件和添加/删除页面是使用 inode 定义文件完成的,但在需要之前不处理实际的磁盘块,在这种情况下,它会清除创建它们。因此,我希望 valloc 系统能够增加数据段交换的大小,而无需实际分配物理或交换页面,或者运行 for 循环来清除所有内容 - 因为文件和分页系统会根据需要执行此操作。因此 valloc 应该比 malloc 快很多。但与 calloc 一样,特殊的 *x/C 风格如何做到这一点取决于他们,而 valloc 手册页对这些期望完全没有帮助。

      传统上这是使用 brk/sbrk 实现的。当然,在虚拟内存系统中,无论是分页系统还是分段系统,都不需要任何这种 brk/sbrk 的东西,只需将文件或地址空间中的最后一个位置扩展到该位置就足够了点。

      重新分配到页面边界,这通常不是用户想要或需要的东西,而是通常是系统想要或需要的东西。

      模拟 valloc 的一种(可能更昂贵的)方法是确定页面边界,然后使用此对齐规范调用 aligned_alloc 或 posix_memalign。

      valloc 已被弃用或已被删除或在某些操作系统中不需要的事实并不意味着它仍然没有用,并且在其他操作系统中无法获得最佳效率。如果它已被弃用或删除,人们会希望有同样有效的替代品(但我不会打赌,而且可能确实已经编写了我自己的 malloc 替代品)。

      在过去的 40 年中,真实内存和(曾经被发明的)虚拟内存的权衡不断变化,主流操作系统倾向于追求装饰而不是效率,而没有(时间或空间)效率的程序员一个重要的当务之急。在嵌入式系统中,效率更为关键,但标准操作系统和/或工具通常不能很好地支持效率。但是,如果有疑问,您可以使用自己的 malloc 替代品来替代您的应用程序来满足您的需求,而不是依赖于其他人醒来并决定执行/实施或撤消/弃用什么。

      所以真正的答案是您不一定要使用 valloc 或 malloc 或 calloc 或您当前的操作系统颠覆提供的任何替代品。

      【讨论】:

      • in which case [memory] is cleared by the OS for security reasons 这完全是错误的。无法保证环境会以这种方式运行。此外,我认为这个答案不会为问题线程添加任何新内容。
      • @Jules - 怎么了?如果您(或 malloc)使用 brk 来获取新内存(可能已被其他用户/进程使用),它确实会被操作系统清除,因为不这样做是一个安全问题。在现代操作系统中,这是在分配物理内存时由虚拟内存系统处理的。说 valloc 已过时(它是否仍然有用取决于操作系统)并不是对这个问题的答案:在所描述的(虚拟内存分配)条件下,valloc 比 malloc 快,这是对何时的原始问题的答案使用 valloc 与 malloc,以及为什么我们有 valloc。
      • In a modern OS -- 你做了一些非常强有力的假设。有许多现代操作系统(例如,在嵌入式和一些物联网应用程序中)没有强制执行某些在通常的桌面和服务器使用操作系统中被视为理所当然的安全措施。顺便说一句,valloc 在许多因弃用而完全删除实现的操作系统上再快不过了。
      • @Jules - 问题不在于是否存在没有 VM 或不强制执行安全性的操作系统,或者 valloc 不会更快,而是何时更适合使用瓦洛克。如果嵌入式系统不支持 VM 或不强制执行安全性,则不太可能需要 valloc。类似地,如果它使用对 VM 系统的页面边界进行优化并避免清除已分配但未使用的内存的 VM 敏感版本的 malloc,那么它也不需要 valloc。然而,传统上,人们编写了自己的 malloc,因为它不是最理想的。
      猜你喜欢
      • 1970-01-01
      • 2011-09-18
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 2019-08-25
      • 2012-06-15
      • 2011-06-26
      相关资源
      最近更新 更多