Linux OOM 机制

之前项目组在一台1核1G开发服务器上协作开发, 服务器上有 Nginx,PHP,Mysql 其他没有耗资源的程序, 随着测试数据上升及开发人员增加(mysql可视化工具长连接也会耗内存) 导致mysql进程经常挂掉, 当时也想到是Mysql太占资源, 但还是没解释通为什么每次挂的都是mysql进程, 直到最近了解了Linux OOM机制。

Linux OOM机制

OOM killer(Out-Of-Memory killer): 该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽内核会把该进程杀掉。

说明:

  1. Linux内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没有实际全部使用
  2. 为了提高性能,这部分没用的内存可以留作它用,这部分内存是属于每个进程的,内核直接回收利用的话比较麻烦,所以内核采用一种过度分配内存(over-commit memory)的办法来间接利用这部分“空闲”的内存,提高整体内存的使用效率。

如果这些分配出去的内存需求超过物理内存(包括swap)的容量, 内核(OOM killer) 必须杀掉一些进程才能保障系统正常运行

检测机制:

内核源码: linux/mm/oom_kill.c

  1. 系统内存不足时, out_of_memory() 被触发
  2. 调用 select_bad_process() 选择一个 “bad” 进程杀掉
  3. 如何判断和选择 “bad” 进程由 oom_badness()决定 <理论上最bad的进程是最占用物理内存消耗量的进程>

oom_badness() 如何选择 哪个进程是 “bad” 进程?

oom_badness() 给每个进程打分, 根据 points 的高低来决定杀哪个进程 (分数越低越不容易被杀掉, points 可以由adj来调节)
打分机制如下:

  • root进程有3%的内存使用特权,因此这里要减去那些内存使用量
  • /proc/PID/oom_score_adj 影响打分 有效值是 -1000到1000之间的整数<-1000 禁止使用 oom killer -500:表示 分数对半折>
  • /proc/PID/oom_adj 已废弃留作兼容, kernel 会换算成oom_score_adj

PS: php-fpm进程 score 正常才 3 分 左右 , Mysql 进程 score 在300左右。。。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!