针对腾讯云 CVM 内存不足导致 OOM Killer 频繁杀死进程的问题,核心解决方案在于优化内存配置与监控。首先应通过 free 或 top 命令确认内存使用情况,若物理内存确实不足,可升级实例配置或增加 Swap 虚拟内存。其次,检查应用是否存在内存泄漏,调整 JVM 或数据库内存参数。此外,可通过修改/proc/
OOM 了?物理内存不够了?试试这个方法来提升内存容量,不花钱的
本文解决的实际问题:当我们物理内存小的时候,会出现 OOM,然后服务自动死掉的情况。因为物理内存大小是固定的,有没有其他好的办法来解决呢?这里我们可以适当调整 Linux 的虚拟内存来协作。问题描述:最近遇到一个情况,物理内存不够,导致项目一两天就自动死掉了。服务器物理内存就 2GB,上面有好多服务,但是,又不能停,导致一个新上的项目,总是过一两天就自己死掉了。查看启动情况:添加虚拟内存前,服务重启情况 从上图中,我们可以看到服务重启的频率,是不是相当的高了。解决这种情况,可以有以下两种方案:一、使用脚本定时查询,如果指定服务没有启动,就执行重启动作;二、能否使用虚拟内存解决呢?其实第一种方案,凯哥 (凯哥 Java:kaigejava) 也尝试过了。最后还是选择试试第二种方案:提高虚拟内存大小,来解决物理内存捉襟见肘的情况呢?在使用虚拟内存前,我们先来看看,当前服务器默认的虚拟内存的使用情况,使用 top 命令查看:添加虚拟内存前 Swap 使用情况 从上图中,我们可以看到,swap 区域的默认大小是 1GB 的,可用空间为 0.这说明,交换区域已经被占满了,看来是需要提高 swap 区大小了。
细说|Linux Out Of Memory 机制
什么是 OOM 机制 是 Out Of Memory 的缩写,中文意思是内存不足。而 是指当系统内存不足时,系统触发的应急机制。当 Linux 内核发现系统中的物理内存不足时,首先会对系统中的可回收内存进行回收,能够被回收的内存有如下:读写文件时的页缓存。为了性能而延迟释放的空闲 slab 内存页。当系统内存不足时,内核会优先释放这些内存页。因为使用这些内存页只是为了提升系统的性能,释放这些内存页也不会影响系统的正常运行。如果释放上述的内存后,还不能解决内存不足的情况,那么内核会如何处理呢?答案就是:触发 杀掉系统中占用内存最大的进程。如下图所示:可以看出,OOM killer 是防止系统崩溃的最后一个手段,不到迫不得已的情况是不会触发的。OOM killer 实现 接下来,我们分析一下内核是如何实现 OOM killer 的。由于在 Linux 系统中,进程申请的都是虚拟内存地址。所以当程序调用 申请内存时,如果虚拟内存空间足够的话,是不会触发 OOM 机制的。
oom 内存溢出进程被杀处理办法
oom 内存溢出进程被杀处理办法 1.由于系统内存不够用,导致一些重要进程被杀 2.修改进程 oom 的优先级 # 这个接口就是/proc/pid/oom_adj, 它的范围是 -17~+15,值越高,就越容易被杀掉,如果把该值设置为 -17,oom 就永远也不会考虑杀它。catoom_setting.sh#使用 cron 定时执行这个脚本 #!/bin/bash # 【重要服务不杀 -17】cat/data/mysql/mysql_master/data/mysql.pid &&echo-17> /proc/`cat/data/mysql/mysql_master/data/mysql.pid`/oom_adj cat/data/mongodb/mongodb_master/pid_mongod.pid &&echo-17> /proc/`cat/data/mongodb/mongodb_master/pid_mongod.pid`/oom_adj cat/data/mysql/mysql_slave/data/mysql.pid &&echo-17> /proc/`cat/data/mysql/mysql_slave/data/mysql.pid`/oom_adj # 【不重要且占用较多内存可停服务,可优先被杀 15,释放内存,找维护时间再处理】cat/data/mongodb/mongodb_slave/pid_mongod.pid &&echo15> /proc/`cat/data/mongodb/mongodb_slave/pid_mongod.pid`/oom_adj 3.oom 原理说明 在 Linux 中当 malloc 返回的是非空时,并不代表有可以使用的内存空间。Linux 系统允许程序申请比系统可用内存更多的内存空间,这个特性叫做 overcommit 特性,这样做可能是为了系统的优化,因为不是所有的程序申请了内存就会立刻使用,当真正的使用时,系统可能已经回收了一下内存。但是,当你使用时 Linux 系统没有内存可以使用时,OOM Killer 就会出来让一些进程退出。
MySQL OOM 故障应如何下手
先介绍下这位朋友:OOM-killer OOM Killer(Out of Memory Killer) 是当系统内存严重不足时 linux 内核采用的杀掉进程,释放内存的机制。OOM Killer 通过检查所有正在运行的进程,然后根据自己的算法给每个进程一个 badness 分数,拥有最高 badness 分数的进程将会在内存不足时被杀掉。它打分的算法如下:某一个进程和它所有的子进程都占用了很多内存的将会打一个高分。为了释放足够的内存来解决这种情况,将杀死最少数量的进程 (最好是一个进程)。内核进程和其他较重要的进程会被打成相对较低的分。上面打分的标准意味着,当 OOM killer 选择杀死的进程时,将选择一个使用大量内存,有很多子进程且不是系统进程的进程。简单来讲,oom-killer 的原则就是损失最小、收益最大,因此它会让杀死的进程数尽可能小、释放的内存尽可能大。在数据库服务器上,MySQL 被分配的内存一般不会小,因此容易成为 oom-killer 选择的对象。“既然发生了 OOM,那必然是内存不足,内存不足这个问题产生原因很多。首先第一个就是 MySQL 自身内存的规划有问题,这就涉及到 mysql 相应的配置参数。另一个可以想到的原因就是一般部署 MySQL 的服务器,都会部署很多的监控和定时任务脚本,而这些脚本往往缺少必要的内存限制,导致在高峰期的时候占用大量的内存,导致触发 Linux 的 oom-killer 机制,最终 MySQL 无辜躺枪牺牲。”
为什么我的进程被 kill 掉了
先来看段代码:这段代码非常简单,就是先用 mmap 的方式,为该进程分配 10GiB 的虚拟内存,然后再用 page 写的方式,让操作系统为这 10GiB 虚拟内存,分配对应的物理内存,最后 sleep,等待我们测试。运行下:没啥问题,和我们预期的一样,正常执行。打开另一个终端,执行以下命令,看下它的内存占用:上图中的 VSZ 指的是虚拟内存,RSS 指的是物理内存,单位都是 KiB,所以该进程虚拟内存和物理内存的使用,都约等于 10GiB,没问题。我们再开个终端,再执行下这个程序:第二次执行这个程序也没问题,但奇怪的是,此时第一次执行的那个程序却被 kill 掉了:这是为什么呢?上面我们说到,该程序的逻辑是分配 10GiB 的物理内存,所以运行两次,也就是要分配 20GiB 的物理内存。但在我们的测试机器上,物理内存一共才 16GiB,所以,运行两个这样的进程肯定是不行的。在第二次执行该程序,且向操作系统申请物理内存时,操作系统会发现,物理内存已经没有了。此时,为了防止整个系统 crash 掉,linux 内核会触发 OOM/Out of Memory killing 机制,即按照一定的规则选择一个进程,将其 kill 掉,以便回收物理内存,以此来保证机器整体的稳定运行。
FAQ
如何确认进程是被 OOM Killer 杀死的?
可以通过执行 dmesg 命令查看内核日志,搜索"Out of memory"或"OOM killer"关键词,若看到相关记录且包含被杀进程名,则确认为 OOM 杀死。
调整 oom_adj 值为 -17 有什么作用?
将/proc/
增加 Swap 虚拟内存能彻底解决 OOM 问题吗?
增加 Swap 可以缓解物理内存不足的压力,避免频繁 OOM,但 Swap 读写速度远低于物理内存,可能导致性能下降,仅作为临时方案。
为什么 MySQL 进程容易成为 OOM Killer 的目标?
MySQL 通常占用大量内存且子进程多,根据 OOM Killer 评分算法,占用内存多且非内核进程的 badness 分数高,容易被选中杀死。