我想使用 mmap 函数将文件映射到内存中,并想知道当前平台上的虚拟内存量是否足以映射一个大文件。对于 32 位系统,我无法映射大于 4 Gb 的文件。
std::numeric_limits<size_t>::max() 给我可寻址内存的数量,或者我应该测试任何其他类型(off_t 或其他)?

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

有帮助吗?

解决方案

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

不过,有一台内存空间共同的平台,两者是平等的,所以你可以逃脱在实践中使用size_t如果你知道目标CPU。

总之,这并不能真正告诉你什么是有用的。当然,一个32位CPU具有4GB存储空间等等size_t是一个32位无符号整数。但是,没有提到多少,你可以分配。内存空间的某些部分是由操作系统使用。和一些部分已经使用自己的应用程序:用于对堆等映射到可执行存储器(以及它可以使用任何动态库),为每个线程的堆栈,分配的存储器

所以,不,技巧如服用size_t的尺寸告诉你,你正在运行的地址空间,但没有非常实用的一点点。你可以问操作系统的内存是如何在你的过程和其他指标的使用,但同样,这并不真正帮助你多少。这是可能的一个进程使用只是一对夫妇兆的,但有分散在许多较小的分配,这是不可能找到的内存大于100MB的连续块,说。因此,在32位机,与使用几乎没有记忆的过程上,你会不会做出这样的分配。 (即使操作系统有一个神奇的WhatIsTheLargestPossibleMemoryAllocationICanMake() API,即还是的就不会帮你的。它会告诉你你需要的从刚才什么的。你有没有保证,答案仍然是通过你试图映射文件时有效。

所以,真的,你能做的最好的是的尝试的映射文件,看它是否失败。

其他提示

您好,您可以使用GlobalMemoryStatusEx和VirtualQueryEx如果在Win32

的编码

事实是,指针的大小并不能告诉您实际上有多少“地址空间”可供您使用,即。可以映射为单个连续块。

它受到以下限制:

  • 操作系统。它可能会选择只提供理论上可能的地址范围的子集,因为操作系统自身的目的需要可映射内存(例如,使显卡帧缓冲区可见,当然也供操作系统本身使用) )。
  • 可配置的限制。在 Linux / UNIX 上,分别使用“ulimit”命令。setrlimit() 系统调用允许以各种方式限制应用程序地址空间的最大大小,Windows 通过注册表参数提供类似的选项。
  • 应用程序的历史记录。如果应用程序广泛使用内存映射,则地址空间可能会产生碎片,从而限制“可用”连续虚拟地址的最大大小。
  • 硬件平台。有些 CPU 的地址空间有“漏洞”;一个例子是 64 位 x86,其中指针仅在 0x0..0x7fffffffffff 或 0xffff000000000000 和 0xffffffffffffffff 之间才有效。IE。您拥有 2x128TB,而不是完整的 16EB。将其视为 48 位“有符号”指针......

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

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

重新改写你的问题“的上限,你可能可以在系统上住址”,是有点误导;它的硬件体系结构相关。有64位架构在那里,其MMU愉快地允许(uintptr_t中)(64位,SPARC)( - 1)有效的地址,即可以映射到的东西64位地址空间的最后一页。无论操作系统允许应用程序这样做与否是再次是完全不同的问题...

有关用户的应用程序,“高标记”不是(总是)固定的先验。这是对例如可调Solaris或Linux。这就是getrlimit(RLIMIT_AS)用武之地。

请注意,再次,通过说明书中,会是什么,以防止(怪异)操作系统设计选择例如放置应用程序栈和堆在“低”的地址,而在“高”地址代码放在一个平台上的地址空间的孔。你需要全64位指针在那里,不能让他们任何较小,但也有可能是从未被提供给您的应用程序“无法访问/无效”范围内的任意数。

您可以尝试sizeof(int*)。这会给你的目标平台上指针的长度(以字节为单位)。因此,你可以找到的可寻址空间有多大。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top