"setrlimit()"不影响正在运行的进程
"setrlimit()" is not affecting the running process
我正在尝试模拟 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 Failuren";
}
}
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
}
示例的跟踪结束:
...
write(1, "ALLOCn", 6ALLOC
) = 6
exit_group(0) = ?
要么增加请求大小,例如在我的情况下至少增加到 1<<16
,要么切换到普通 C,都会导致分配请求从操作系统提供服务,然后限制确实适用:
使用1<<16
分配请求结束跟踪:
write(1, "ALLOCn", 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++ libboost 运行进程并获取其输出?
- 如何运行进程,然后在它退出时收到通知
- 在特定监视器上运行进程
- 使用Runtime.exec从Java运行进程-退出代码139
- 使用C++将CPU专用于在1个核心上运行进程
- 如何找到运行进程的物理套接字 ID/编号
- 如果从文件中读取,则无法按文件名运行进程
- 如何判断进程的用户令牌是否与运行进程的登录会话令牌相同?
- 在 C 语言的后台运行进程
- 在C++中获取带有 Windows 7 API 的运行进程
- r语言 - 如何直接在数据库服务器上运行C++进程以避免传输数据集
- 在虚拟文件系统中运行进程
- 检查是否已运行进程和通信的副本
- c++,总是运行进程或调用可执行文件
- 运行进程命令行
- 如何使用编程方法拦截linux上运行进程中调用的系统调用
- 使用c++获取当前运行进程中的X显示变量
- 获取当前运行进程的网络适配器
- 如何将ShellExecuteEx作为在父级退出后关闭的子级运行进程
- 在多核 (Linux) 中运行进程的命令行参数是什么