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

虚拟内存、物理内存与OOM Killer

文章目录

  • 虚拟内存、物理内存与OOM Killer
    • 问题描述
    • 问题分析
    • 为什么资源成功创建但使用该资源的内存会出现异常呢?
    • 虚拟内存和物理内存
    • 延迟映射
      • 测试代码
      • 监测系统资源
    • OOM Killer
      • 测试代码
      • 结果分析
    • 如何防止进程被OOM Killer杀掉

虚拟内存、物理内存与OOM Killer

问题描述

测试环境中集群部署(各个节点功能相同)部署在同一主机上,启动时无异常,运行一段时间后,每个节点的进程组中的进程会出现异常终止的现象,且异常终止的进程并不完全相同。

问题分析

1.多节点同时部署改为单节点手动部署,每部署一个节点后等待十分钟。
前两个节点成功完成了部署,然而第三个节点的某一进程无法启动导致后面的进程也无法照常启动,但与同时启动多个节点不同的是前两个节点的进程无异常可以正常工作。
2.分析启动失败的进程
该进程的功能为向下游发送数据,因前两个节点的全部进程无异常,问题可能并没有出现在该进程上,再次检查第三个节点进程组的运行状态发现其中曾经成功启动的进程也有几个被kill掉。
3.分析第三节点被kill掉的进程
分析各进程的功能后定位在一个读取参考文件的进程上,因集群不做持久化存储,会将存储网关中的大量数据读入到共享内存,初步分析为系统资源不足导致进程出现异常。
4.开发机复现并使用脚本实时进程监控系统资源
测试结果为物理内存和交换区空间即将全部用尽时部分进程开始出现异常,并释放了大量使用的内存空间,确认该问题为内存资源不足所导致的。

为什么资源成功创建但使用该资源的内存会出现异常呢?

shmget 用于创建或获取一个共享内存标识符,该标识符用于唯一标识一个共享内存区域。这个调用通常在创建共享内存时被使用。shmat 用于将共享内存附加到进程的地址空间,使得进程可以访问共享内存中的数据。这个调用通常在进程需要使用共享内存时被使用。
**这两个调用并不直接涉及立即绑定物理内存。**相反,它们是在虚拟地址空间中创建共享内存的映射。物理内存的分配和映射是在共享内存区域被实际使用时发生的。这种延迟的方式使得系统能够更好地管理内存,只有在需要时才分配物理内存。malloc也同样如此。

虚拟内存和物理内存

**虚拟内存:**是一个抽象概念,虚拟内存使得进程可以拥有一块儿从0开始连续的、独立的内存空间,虚拟内存通过映射技术将虚拟地址映射到物理地址或磁盘的交换空间中。
**物理内存:**物理内存是计算机硬件实际存在的内存。

延迟映射

默认情况下,Linux 采用乐观的内存分配策略。 这意味着,当 malloc() 返回非空时,并不能保证内存真的可用。 万一系统内存不足时,一个或多个进程将被 OOM Killer杀死。

~/Code/mem (main*) » man malloc 
...
NOTESBy default, Linux follows an optimistic memory allocation strategy.  This means that when malloc() returns non-NULL there is no guarantee that the memory really is available.  Incase  it  turns  out that the system is out of memory, one or more processes will be killed by the OOM killer.  For more information, see the description of /proc/sys/vm/overcom‐mit_memory and /proc/sys/vm/oom_adj in proc(5), and the Linux kernel source file Documentation/vm/overcommit-accounting.rst.
...

测试代码

#include <cstdlib>
#include <cstring>
#include <unistd.h>using namespace std;int main(int, char **) {constexpr size_t memory_block = 1024 * 1024 * 1024;// 分配10g虚拟内存空间void *p = malloc(10 * memory_block);// 访问前1g内存空间memset(p, 0, memory_block);sleep(1000);return 0;
}

监测系统资源

使用free -h查看真实使用的内存空间
物理内存和交换区总共使用的内存并没有达到10g,表明没有将申请的10g内存空间全部映射到物理内存中。

~/Code/NetExample/app/bin (main*) » free -htotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       3.4Gi       3.9Gi       0.0Ki       517Mi       4.2Gi
Swap:          8.0Gi       219Mi       7.8Gi

使用top命令
分配了10g的内存空间,但是只映射了其中使用memset访问的1g的内存

~/Code/NetExample/app/bin (main*) » top
...
761182 ubuntu    20   0   10.0g   1.0g   2.3m S   0.0  12.9   0:00.32 mem
...

OOM Killer

Out-of-Memory (OOM) Killer 是 Linux 内核中的一个机制,用于处理系统内存耗尽的情况。当系统内存不足,没有可用的物理内存和交换空间时,OOM Killer 会尝试终止一个或多个进程,以释放内存,从而防止系统死机或变得不可用。

OOM Killer的策略为杀掉最少进程数尽可能多的释放内存

测试代码

#include <cstdlib>
#include <cstring>
#include <format>
#include <iostream>using namespace std;int main(int, char **) {constexpr size_t memory_block = 1024 * 1024 * 1024;size_t block_size = 0;while (true) {void *p = malloc(memory_block);if (p != nullptr) {++block_size;}cout << format("malloced {}g virtual memory\n", block_size);memset(p, 0, memory_block);cout << format("used {}g physical memory\n", block_size);system("free -h");cout << endl;}return 0;
}

结果分析

可从虚拟内存映射到物理内存中内存大小为剩余物理内存空间(Mem中的available)和剩余交换空间(Swap中的free)的总和。在进程被kill前虽然成功申请到了虚拟内存空间,但是却因为没有足够的物理空间大小导致OOM Killer开始清理进程。

~/Code/mem (main*) » app/bin/mem
malloced 1g virtual memory
used 1g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       3.3Gi       4.0Gi       0.0Ki       397Mi       4.2Gi
Swap:          8.0Gi       140Mi       7.9Gimalloced 2g virtual memory
used 2g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       4.3Gi       3.0Gi       0.0Ki       397Mi       3.2Gi
Swap:          8.0Gi       140Mi       7.9Gimalloced 3g virtual memory
used 3g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       5.3Gi       2.0Gi       0.0Ki       397Mi       2.2Gi
Swap:          8.0Gi       140Mi       7.9Gimalloced 4g virtual memory
used 4g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       6.3Gi       1.0Gi       0.0Ki       397Mi       1.2Gi
Swap:          8.0Gi       140Mi       7.9Gimalloced 5g virtual memory
used 5g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.3Gi        86Mi       0.0Ki       339Mi       257Mi
Swap:          8.0Gi       140Mi       7.9Gimalloced 6g virtual memory
used 6g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi        99Mi       0.0Ki        55Mi        37Mi
Swap:          8.0Gi       924Mi       7.1Gimalloced 7g virtual memory
used 7g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi       133Mi       0.0Ki        58Mi        74Mi
Swap:          8.0Gi       1.9Gi       6.1Gimalloced 8g virtual memory
used 8g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi        75Mi       0.0Ki        58Mi        16Mi
Swap:          8.0Gi       2.9Gi       5.1Gimalloced 9g virtual memory
used 9g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi        88Mi       0.0Ki        56Mi        27Mi
Swap:          8.0Gi       3.9Gi       4.1Gimalloced 10g virtual memory
used 10g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi        66Mi       0.0Ki        60Mi       7.0Mi
Swap:          8.0Gi       4.9Gi       3.1Gimalloced 11g virtual memory
used 11g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi       118Mi       0.0Ki        63Mi        61Mi
Swap:          8.0Gi       5.9Gi       2.1Gimalloced 12g virtual memory
used 12g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi        81Mi       0.0Ki        68Mi        26Mi
Swap:          8.0Gi       6.9Gi       1.1Gimalloced 13g virtual memory
used 13g physical memorytotal        used        free      shared  buff/cache   available
Mem:           7.7Gi       7.6Gi        76Mi       0.0Ki        66Mi        21Mi
Swap:          8.0Gi       7.9Gi       125Mimalloced 14g virtual memory
[1]    756754 killed     app/bin/mem
------------------------------------

如何防止进程被OOM Killer杀掉

可以通过修改/proc/sys/vm/overcommit_memory或/proc/sys/vm/oom_adj的值来修改进程的分数或禁止OOM Killer。
但是这不是一个完美的解决方案,一个高可用进程更应该从这两点下手:
1.部署在具有充足的硬件资源的机器上
2.做好应急方案,在内存到达80%即将耗尽及时通知并处理

http://www.lryc.cn/news/2417122.html

相关文章:

  • SurfaceView和View区别总结
  • html table th分层,html中 table的结构 彻底搞清 caption th thead等
  • tsearch, tfind, tdelete, twalk, tdestr函数—标准树
  • 『TopCoder 组件开发指南』
  • 创建共享网盘、访问共享网盘
  • ubuntu切换软件源为国内源
  • windows 2000 系统安装和配置
  • 修改Win10右键菜单
  • 机器学习——RBF神经网络
  • 信息增益与信息增益率详解
  • 11个超高清图片素材网站,可直接访问
  • oVirt4.4单台主机Allinone部署(非HostedEngine方式)
  • 用户登录模块
  • 为什么要进行透明计算和透明计算是什么
  • UDP协议的两个主要方法sendto和recvfrom详解
  • 猫头虎分享已解决Bug || 代理服务器错误(Proxy Server Error):ProxyFailure, ProxyConnectionRefused
  • 【虚幻引擎】UE4 同步和异步资源加载(软引用)
  • Android设备唯一标识(终极方案!)
  • weak reference的介绍
  • yumdownloader介绍和使用示例
  • 正则表达式语法及使用
  • DM脚本启动报错:please change nobody or root to execute the service script,otherwise may be failed
  • USBKEY全解析---概要介绍
  • Java 程序的运行环境及示例代码
  • 日志过滤实体中的属性
  • EtherCAT运动控制卡开发教程之Qt(上):开发环境配置与简单运动控制应用
  • usb一致性测试软件,USB 3.0一致性测试方法
  • EasyExcel 样式注解大全
  • 【计算机网络】网络安全知识要点
  • 【MATLAB安装教学】图文并茂手把手教学