发布
社区首页 >问答首页 >如何获得C++中可用的虚拟内存量?

如何获得C++中可用的虚拟内存量?
EN

Stack Overflow用户
提问于 2010-11-18 21:15:36
回答 5查看 1.8K关注 0票数 3

我想使用mmap函数将文件映射到内存中,并想知道当前平台上的虚拟内存量是否足以映射一个巨大的文件。对于32位系统,我不能映射大于4 Gb的文件。

std::numeric_limits<size_t>::max()是否会给我提供可寻址内存的大小,或者我是否应该测试其他类型(off_t或其他类型)?

正如Lie Ryan在他的评论中指出的那样,这里的“虚拟内存”被滥用了。然而,问题仍然存在:有一个与指针关联的类型,它具有最大值,该值定义了您可以在系统上访问的上限。这是什么类型?是size_t还是ptrdiff_t?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-11-18 21:53:28

size_t只需要足够大来存储最大可能的单个连续对象。这可能与地址空间的大小不同(例如,在具有分段内存模型的系统上)

但是,在具有扁平内存空间的常见平台上,这两者是相等的,因此,如果您知道目标CPU,则可以在实践中使用size_t

无论如何,这并不能告诉你任何有用的东西。当然,32位的CPU有4 4GB的内存空间,所以size_t是一个32位的无符号整数。但这并没有说明你能分配多少。内存空间的一部分由操作系统使用。而且有些部分已经被您自己的应用程序使用:用于将可执行文件映射到内存(以及它可能使用的任何动态库)、每个线程的堆栈、堆上分配的内存等等。

所以不会,像计算size_t大小这样的技巧会告诉你一些关于你正在运行的地址空间的信息,但是没有什么非常有用的。您可以向操作系统询问您的进程和其他指标使用了多少内存,但同样,这对您没有多大帮助。有可能一个进程只使用几兆字节,但它分散在太多的小分配上,以至于不可能找到大于100MB的连续内存块。因此,在32位机器上,进程几乎不使用内存,您不太可能进行这样的分配。(即使操作系统有一个神奇的WhatIsTheLargestPossibleMemoryAllocationICanMake()应用程序接口,也不会对你有任何帮助。它会告诉你刚才你需要什么。您不能保证在您尝试映射文件时答案仍然有效。

因此,实际上,您所能做的最好的事情就是尝试映射文件,看看是否失败。

票数 1
EN

Stack Overflow用户

发布于 2010-11-18 21:19:30

您好,如果您使用win32编码,则可以使用GlobalMemoryStatusEx和VirtualQueryEx

票数 1
EN

Stack Overflow用户

发布于 2010-11-19 00:22:11

问题是,指针的大小并不能告诉你实际有多少“地址空间”可用,也就是说,可以被映射为一个连续的块。

它受到以下因素的限制:

  • 操作系统。它可能会选择只向您提供理论上可能的地址范围的一个子集,因为可映射内存是用于操作系统自身的目的(例如,使显卡帧缓冲区可见,当然也供操作系统itself).
  • configurable限制使用)。在Linux / UNIX上,"ulimit“命令分别为:setrlimit()系统调用允许以各种方式限制应用程序的地址空间的最大大小,并且Windows通过应用程序的注册表parameters.
  • the历史记录具有类似的选项。如果应用程序广泛使用内存映射,地址空间可能会碎片限制“可用”连续虚拟地址的最大大小。
  • 硬件平台。一些CPU有带“洞”的地址空间;64位x86就是一个例子,其中指针只有在0x0..0x7fffffffffffffff或0xffff000000000000和0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff例如,您有2x128TB,而不是完整的16EB。可以把它看作是48位的“带符号”指针……

最后,不要混淆“可用内存”和“可用地址空间”。执行malloc(someBigSize)和mmap(...,someBigSize,...)是有区别的因为前者可能需要物理内存的可用性来容纳请求,而后者通常只需要足够大的空闲地址范围。

对于UNIX平台,部分答案是使用getrlimit(RLIMIT_AS),因为这给出了应用程序当前调用的上限-如上所述,用户和/或管理员可以对此进行配置。您可以保证,任何尝试mmap大于该值的区域都将失败。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4215127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档