回收内存方式:后台回收:直接回收
- 一种是后台内存回收,也就是唤醒 kswapd 内核线程,这种方式是异步回收的,不会阻塞进程 。
- 一种是直接内存回收,这种方式是同步回收的,会阻塞进程,这样就会造成很长时间的延迟,以及系统的 CPU 利用率会升高,最终引起系统负荷飙高 。
- 文件页的回收:对于干净页是直接释放内存,这个操作不会影响性能,而对于脏页会先写回到磁盘再释放内存,这个操作会发生磁盘 I/O 的,这个操作是会影响系统性能的 。
- 匿名页的回收:如果开启了 Swap 机制,那么 Swap 机制会将不常访问的匿名页换出到磁盘中,下次访问时,再从磁盘换入到内存中,这个操作是会影响系统性能的 。
如何降低内存回收的影响
- 从文件页和匿名页的回收操作来看,文件页的回收操作对系统的影响相比匿名页的回收操作会少一点,因为文件页对于干净页回收是不会发生磁盘 I/O 的,匿名页的 Swap 换入换出这两个操作都会发生磁盘 I/O 。
- 尽早触发 kswapd 内核线程异步回收内存 来避免应用程序进行直接内存回收 。
Linux 到底是根据什么标准来选择被杀的进程呢?这就要提到一个在 Linux 内核里有一个 oom_badness() 函数,它会把系统中可以被杀掉的进程扫描一遍,并对每个进程打分,得分最高的进程就会被首先杀掉 。
进程得分的结果受下面这两个方面影响:
- 第一,进程已经使用的物理内存页面数 。
- 第二,每个进程的 OOM 校准值 oom_score_adj,我们可以在设置 -1000 到 1000 之间的任意一个数值,调整进程被 OOM Kill 的几率 。
// points 代表打分的结果
// process_pages 代表进程已经使用的物理内存页面数
// oom_score_adj 代表 OOM 校准值
// totalpages 代表系统总的可用页面数
points = process_pages + oom_score_adj * totalpages / 1000
计算出来的值越大,那么这个进程被 OOM Kill 的几率也就越大 。
每个进程的 oom_score_adj 默认值都为 0,所以最终得分跟进程自身消耗的内存有关,消耗的内存越大越容易被杀掉 。我们可以通过调整 oom_score_adj 的数值,来改成进程的得分结果:
- 如果你不想某个进程被首先杀掉,那你可以调整该进程的 oom_score_adj,从而改变这个进程的得分结果,降低该进程被 OOM 杀死的概率 。
- 如果你想某个进程无论如何都不能被杀掉,那你可以将 oom_score_adj 配置为 -1000 。
不建议将我们自己的业务程序的 oom_score_adj 设置为 -1000,因为业务程序一旦发生了内存泄漏,而它又不能被杀掉,这就会导致随着它的内存开销变大,OOM killer 不停地被唤醒,从而把其他进程一个个给杀掉 。
推荐阅读
- 服务器Linux系统配置mysql数据库主从自动备份
- Oracle数据库初始化参数解析:优化系统配置的终极指南!
- linux 是如何进行内存分配的
- TypeScript接口与类 - 类型系统高级用法
- 门禁系统安装步骤 门禁系统安装方法
- 秒懂分账系统的工作原理
- oppo手机怎么清理内存 Oppo手机怎么清理内存空间?
- 陈凯歌新片海报背后,每个细节都写满了算计,网友:用心险恶
- ghostWindows系统介绍
- Kubernetes 微内核的分布式操作系统