gpt4 book ai didi

c++ - "setrlimit()"不影响正在运行的进程

转载 作者:太空狗 更新时间:2023-10-29 12:22:23 28 4
gpt4 key购买 nike

我正在尝试模拟 Linux 中进程的错误场景,即堆不足以在 C++ Linux 应用程序中分配内存。但是即使我使用“setrlimit”来减少进程可用的堆内存,堆内存仍然被成功分配。

struct rlimit the_limit = { 1, 1 };
if (-1 == setrlimit(RLIMIT_DATA, &the_limit)) {
perror("setrlimit failed");
}

try
{
char *n = new char[5600];

if (n==NULL)
{
cout <<"\nAllocation Failure\n";
}
}
catch (std::bad_alloc& ba)
{
std::cerr << "bad_alloc caught: " << ba.what() << '\n';
}

最佳答案

大多数 C++ 标准库,包括随 g++ 一起提供的库,都以一些预分配的堆内存开始。5600 是一个小请求,因此,在我的 Linux 系统上,它从预分配的内存中得到满足,这证明来自 strace :

修改示例:

#include <stdio.h>
#include <sys/resource.h>
int main()
{
struct rlimit the_limit = { 1, 1 };
if (-1 == setrlimit(RLIMIT_DATA, &the_limit)) { perror("setrlimit failed"); }

puts("ALLOC");
#if __cplusplus
try { char *n = new char[5600]; } catch (...) { perror("alloc failure"); }
#else
{ char *n = malloc(1); if(!n) perror("alloc failure"); }
#endif
}

示例的 strace 结束:

...
write(1, "ALLOC\n", 6ALLOC
) = 6
exit_group(0) = ?

要么增加请求大小,例如在我的情况下至少1<<16 ,或切换到纯 C,导致从操作系统提供分配请求,然后限制适用:

strace 以 1<<16 结尾分配请求:

write(1, "ALLOC\n", 6ALLOC
) = 6
brk(0x561bcc5d4000) = 0x561bcc5b2000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
dup(2) = 3
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 14), ...}) = 0
write(3, "alloc failure: Cannot allocate m"..., 38alloc failure: Cannot allocate memory
) = 38
close(3) = 0
exit_group(0) = ?

请注意,通用分配器实现通常使用 sbrk和/或 mmap直接从操作系统获取内存,正如您可以从 setrlimit 中收集到的那样联机帮助页,RLIMIT_DATA将仅适用于 mmap -如果您使用的是 Linux >= 4.7,则支持分配。

关于c++ - "setrlimit()"不影响正在运行的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57074877/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com