当前位置: 首页 > news >正文

linux进程管理之从内存/cpu角度使用setrlimirt/rlimit

1,setrlimirt/rlimit的使用

#include <sys/resource.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>int main() 
{// 设置内存限制struct rlimit rl;getrlimit(RLIMIT_AS, &rl);// 获取当前内存限制rl.rlim_cur = 1024 * 1024;// 设置软限制为1MBrl.rlim_max = 2048 * 1024;// 设置硬限制为2MBsetrlimit(RLIMIT_AS, &rl);// 应用内存限制// 内存泄露部分int *ptr;while(1){// 无限循环ptr = (int *)malloc(10000000 * sizeof(int));// 分配内存// 不释放内存,造成内存泄露printf("Allocated memory, total usage: %ld KB\n", (long)(rl.rlim_cur / 1024));sleep(1);// 休眠1秒,方便观察内存增长}return 0;
}

运行后触发oom

  1. OOM killer机制
    • Linux内核有OOM killer(Out Of Memory killer)机制
    • 当系统内存不足时,会杀掉占用内存过多的进程
    • 通过调用outofmemory()和selectbadprocess()选择一个"bad"进程杀掉
    • 判断"bad"进程的标准是最占用内存的进程
  2. 内存泄漏导致进程挂死的机制

    • 内存泄漏会导致进程不断申请内存但不释放
    • 当系统内存被耗尽时,OOM killer会杀掉这个进程
    • 进程被杀后会显示为"挂死"状态

使用时需要设置相关参数

echo 2 > /proc/sys/vm/overcommit_memory

参数说明:

取值模式行为说明
0启发式策略(默认)内核估算可用内存,允许少量超量分配,但会拒绝明显无效的大内存请求
1总是允许超量分配接受所有内存申请,直到物理内存+Swap耗尽
2严格限制超量分配内存分配上限 = (物理内存 × overcommit_ratio/100) + Swap

# 查看系统日志中的OOM Killer记录

grep "Out of memory" /var/log/messages
grep "Out of memory" /var/log/syslog
egrep -i -r 'killed process' /var/log
dmesg | grep "Out of memory"

Linux支持多种资源限制类型,主要包括:

  • RLIMIT_CPU:限制进程累计CPU使用时间
  • RLIMIT_FSIZE:限制文件大小
  • RLIMIT_AS:限制进程地址空间大小(虚拟内存)
  • RLIMIT_DATA:限制数据段大小
  • RLIMIT_STACK:限制栈大小

3,栈内存泄露导致挂死问题

#include <sys/resource.h>
#include <stdio.h>void stack_overflow() {char array[1000000];// 声明一个大数组,这将耗尽栈空间printf("This will not be printed\n");
}int main() 
{struct rlimit rlim;rlim.rlim_cur = 2048;// 设置栈大小限制为2048字节rlim.rlim_max = 2048;if (setrlimit(RLIMIT_STACK, &rlim) == -1) {perror("setrlimit");return 1;}stack_overflow();return 0;
}

lark@ubuntu:~$ ./rlimit_over 
Segmentation fault (core dumped)

lark@ubuntu:~$ dmesg | grep "rlimit_over"
[ 1211.633844] rlimit_over[2551]: segfault at 7ffe3812a070 ip 0000558d8b38f1c0 sp 00007ffe3812a070 error 6 in rlimit_over[558d8b38f000+1000]

 

启用CONFIG_DEBUG_STACKOVERFLOW时,内核会在栈底设置保护页(Guard Page),触发访问时抛出SIGSEGV信号  ,在许多系统中,栈是从高地址向低地址增长的,栈指针指向栈顶。

RLIMIT_STACK可能设置了一个最大地址,栈不能超过该地址。

因此,如果栈指针尝试移动到超过RLIMIT_STACK设置的地址以下的位置,它会触发SIGSEGV。

其他的RLIMIT_CPU,RLIMIT_FSIZE,RLIMIT_DATA使用方法类似。

 

相关文章:

  • 【题解-洛谷】P1706 全排列问题
  • 露亦如电 · 时之沙 | 让遗憾在灰烬里随风而去
  • natapp 内网穿透失败
  • windows使用脚本杀死python进程
  • c++ —— 内存管理
  • SWE-Dev:开启自主特征驱动软件开发新纪元,重新定义大模型编码能力边界
  • DAY 44 预训练模型
  • 嵌入式知识篇---Zigbee串口
  • 高保真组件库:数字输入框
  • NT6打印机共享修复工具Fixprint系统补丁
  • Go深入学习延迟语句
  • Python 函数全攻略:函数基础
  • C++课设:简易科学计算器(支持+-*/、sin、cos、tan、log等科学函数)
  • 【MySQL】10.事务管理
  • 滴滴 服务端 面经
  • 【51单片机】2. 进阶点灯大师
  • dxcam 略记~
  • Python-进程
  • 打卡day47
  • day 27 装饰器函数
  • 电子商务网站建设(论文/网站搜索引擎优化的基本内容
  • wordpress 插件有后门/seo优化服务价格
  • 做响应式网站的菜单/网络营销案例分析ppt
  • 汉化主题做网站效果图/广州疫情最新情况
  • 合肥品牌网站建设/女孩短期技能培训班
  • 广州网站制作是什么/推广之家app