
[英]Why does template parameter deduction fail when calling the constructor like this?
[英]Why does calling mmap() with large size not fail?
我尝试使用mmap()
来操纵虚拟内存。 我想保留并提交一个内存区域。 我测试了这段代码:
const unsigned long gygabyte = 1024 * 1024 * 1024;
const unsigned long gygabyteCount = 2;
const unsigned long maxCapacity = gygabyteCount * gygabyte;
int main()
{
char* pMemory;
pMemory = (char*)mmap(NULL, maxCapacity, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if ( mprotect(pMemory, maxCapacity, PROT_READ | PROT_WRITE) != 0 )
{
cout << "Memory Allocation has failed" << endl;
}
usleep(-1);
return 0;
}
我从终端运行了我的程序的多个副本(例如6)。 我从没看过“内存分配失败”。 我在具有4GB RAM的64位Ubuntu上运行。 谁能告诉我一些有关此的信息?
mmap
保留了进程的虚拟地址空间的一个区域,但没有立即为其分配物理RAM。 因此,在64位平台上,您可以保留大量资源而不会出现故障(尽管您仍然需要检查是否有故障;示例代码不需要)。 RAM的物理页在以后访问内存时分配。
mprotect
只是更改保留内存的读/写访问权限; 它也不会使其驻留在RAM中。 通过传递PROT_READ | PROT_WRITE
您将获得相同的效果PROT_READ | PROT_WRITE
PROT_READ | PROT_WRITE
而不是PROT_NONE
进行mmap
,并删除对mprotect
的调用。
如果您需要立即将内存驻留在RAM中,则可以使用mlock
。 如果没有足够的RAM,它将失败。 在许多Linux平台(包括Ubuntu)上,存在资源限制( RLIMIT_MEMLOCK
),该限制限制了任何进程可以锁定的内存量。 您可以使用ulimit -l
进行调整。
mmap对于准备所需的内存映射很有用,但不会将其分配给程序。 内核负责,当你访问它分配内存,这样的mmap
-ing 8 GB有可能在一个4GB内存,如果不同时访问这些8GB。
您应该首先检查mmap
的结果。 如果返回MAP_FAILED
,则表示分配失败。 内核实际上不会一次分配太多内存,而是在您访问该块的相应区域时按需映射物理或交换的空间。
在您的特定情况下,您不需要单独调用mprotect
,因为可以在调用mmap
时为整个区域传递这些标志:
pMemory = mmap(NULL, maxCapacity,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (pMemory == MAP_FAILED) {
/* allocation failed */
}
首先,您必须告诉Linux您希望它执行提交记帐:
echo "2" > /proc/sys/vm/overcommit_memory
否则,它将保留传统的默认设置(从Linux作为玩具操作系统时开始),即允许无限的过量使用,并在物理内存用尽时使应用程序严重崩溃。
另外,正如其他人所说,您需要对照MAP_FAILED
检查mmap
的返回值,而无需使用mprotect
。 只需将正确的PROT_*
值传递给mmap
就可以了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.