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

RHCA08内存管理

内存调优、溢出与泄露及相关架构笔记

一、内存调优

(一)内存过量分配

  1. 物理内存与虚拟内存概念
    • 虚拟地址空间特性:每个进程拥有独立线性连续地址空间,地址范围因架构而异,x86架构和x86_64架构(RHEL8系统)支持不同的最大地址空间。
    • 物理地址空间特性:借助MMU(内存管理单元)完成地址转换,物理页可非连续分布,内存页来源包括RAM和swap空间。
  2. 虚拟内存与物理内存关系
    • 虚拟内存本质:是应用程序申请的内存空间(如Firefox浏览器占用的内存),呈现为连续的线性地址空间。32位架构和64位架构支持不同范围的地址空间,且虚拟内存必须映射到物理内存,swap空间也属于物理内存的一部分。
  3. 内存页大小与分配
    • 页大小标准:x86架构默认4096字节(4KB),ARM架构默认65536字节(64KB)。
    • 分配特性:内存管理的最小单位是页(类似文件系统的block size),应用程序至少占用一个页的空间,可通过命令getconf -a | grep -i pagesize查看系统页大小。
  4. 应用程序内存占用示例:以Firefox进程ID 5141为例,其虚拟内存和物理内存占用有相应数值,且所有内存分配均为页大小的整数倍(如4KB的倍数),可通过pmap命令查看进程内存映射详情,内存地址编号显示为连续的虚拟地址空间。
  5. 基本概念与配置参数
    • 基本概念:又称overcommit或内存复用,允许分配的内存超过实际物理内存,在虚拟化中称为内存共享(如华为实现150%超分配)。
    • 配置参数vm.overcommit_memory有三种模式,0为试探性过量分配(heuristic overcommit),1为总是允许过量分配(always overcommit),2为基于交换空间加内存百分比(commit all swap plus RAM percentage);vm.overcommit_ratio控制过量分配比例。
    • 应用场景:主要用于虚拟化环境提高资源利用率,需特别注意实际内存使用监控,实验演示中部分功能效果未完全展示。
  6. 内存过量分配机制
    • 测试工具:课程专门开发的bigmem程序,用于模拟大内存分配场景,且必须使用红帽8系统中的bigmem版本,因其新增了试探策略。
    • 过量分配策略类型
      • 策略0(默认):试探性过量分配,系统根据当前资源情况谨慎分配,实际分配量不超过物理内存+swap,测试中分配3.5GB(1.5G内存+2G swap)后无法继续分配更大内存。
      • 策略1:无条件过量分配,允许应用程序申请任意大小的虚拟内存,可能导致系统崩溃,测试中可成功分配20GB虚拟内存(实际物理内存不足)。
      • 策略2:基于公式的分配,允许分配量= swap总量 + (物理内存×overcommit_ratio%),默认比例50%(可通过vm.overcommit_ratio调整)。
    • 关键参数说明vm.overcommit_memory是策略选择开关(0/1/2),vm.overcommit_ratio仅策略2有效,设置物理内存的过量分配百分比。测试验证,当ratio=50%时,最大可分配3GB(2G swap + 1.5G×50%);调整ratio=150%后,可分配4GB(2G swap + 1.5G×150%)。
    • 应用场景对比:策略0适用于常规服务器环境,保证系统稳定性;策略1适用于虚拟化环境,确保虚拟机能够启动(不保证性能);策略2适用于需要精确控制内存分配的企业级应用。操作建议,虚拟化环境中可适当提高overcommit_ratio(如150%)。
    • 实验操作记录:策略1下分配超大内存可能导致进程被OOM killer终止,生产环境修改前需评估业务需求和服务承载能力。

(二)通过缓存提升读性能

  • 缓存机制:系统会将读取的文件内容保留在内存中,形成读缓存。
  • 性能提升原理:当再次读取相同文件时,直接从内存读取而非磁盘,显著提高读取速度。
  • 操作示例:清空缓存命令为sysctl -w vm.drop_caches=3;首次复制耗时real 0m0.640s,缓存命中后复制耗时real 0m0.098s(速度提升约6.5倍)。
  • 缓存类型:读缓存专门用于提升读性能,与写缓存机制不同。

(三)利用脏页提升写性能

  • 脏页机制:系统将写入操作先在内存中缓存(形成脏页),延迟写入磁盘。
  • 性能提升原理:将随机IO在内存中整合为顺序IO,减少磁盘寻道时间,提高写入效率。
  • 监控方法:查看脏页大小可使用命令cat /proc/meminfo | grep Dirty,实时监控命令为watch -n .5 cat /proc/meminfo | grep Dirty
  • 内存状态指标:Dirty值表示待写入磁盘的数据量(示例中为8kB),其他相关指标包括Writeback(正在回写的数据量)、Buffers、Cached等。

(四)内存调优参数设置

  1. 脏页比例设置:系统整体脏页比例上限为30%(vm.dirty_ratio=30),单个进程脏页比例上限为10%(vm.dirty_background_ratio=10),脏页回收时间设置为3000厘秒(vm.dirty_expire_centisecs=3000),脏页回写间隔为500厘秒(vm.dirty_writeback_centisecs=500)。
  2. 内存交换策略:通过swappiness参数控制内存交换倾向,取值范围0-100,默认值60。低值(接近0)优先保留内存缓存,减少交换;高值(接近100)更积极使用交换空间。在内存紧张时需要权衡缓存释放与交换使用。

(五)内存溢出OOM解决方案

  1. 内存溢出Killer
    • 定义:当系统所有内存(包括swap)都被占用时触发的保护机制,通过终止进程防止系统崩溃。
    • 触发条件:物理内存和交换空间全部耗尽,系统处于"all memory active"状态。
    • 工作机制:具有自救机制,优先杀死特定进程而非导致系统死机;在/var/log/messages中记录"Out of memory: Kill process"事件;基于oom_score值决定终止进程的优先级。
    • 关键文件/proc/[pid]/oom_adj用于调整进程被杀优先级(-17到15),/proc/[pid]/oom_score是计算得出的被杀概率值,/proc/sysrq-trigger可手动触发内存管理操作。
    • 参数调整:取值范围为-17(最不可能被杀)到15(最可能被杀),值越小进程存活概率越高。oom_score由系统根据内存占用和oom_adj值动态计算,用户不可直接修改。
    • 系统请求功能:触发方式为echo f > /proc/sysrq-trigger,作用是模拟内存紧张场景,主动调用OOM killer,会生成"Manual OOM execution"系统日志。
  2. 例题:vsftpd内存调整
    • 操作步骤:查找进程ID使用pidof vsftpd,进入进程目录执行cd /proc/[pid],然后调整保护级别。
    • 验证方法:通过tail -f /var/log/messages观察kill事件,测试不同oom_adj值对应的oom_score变化规律。
    • 注意事项:新版系统推荐使用oom_score_adj替代oom_adj;关键服务应设置为负值(如-17),非关键服务可设为正值;无法设置为超出-17~15范围的值,尝试设置-18会报错。

二、内存溢出

(一)内存溢出解决方案

  • OOM Killer机制:当系统内存耗尽时,内核会扫描所有进程,根据oom_score值决定杀死哪个进程。
  • 评分标准:进程的oom_score值范围是0-1000,值越高越容易被杀死。例如vsftpd进程被杀死是因为其score值为999。
  • 处理流程:系统会优先杀死分数最高的进程,如果问题未解决则继续杀死其他进程。

(二)out of memory killer

  1. 参数调整:通过/proc/pid/oom_adj文件可以调整进程的OOM优先级。
  2. 优先级规则:取值范围-17到15,值越小优先级越高(越不容易被杀死)。
  3. 持久化设置:在服务启动脚本中通过echo -17 > /proc/[pid]/oom_adj实现永久生效。
  4. 死机相关
    • 死机触发命令:模拟命令echo c > /proc/sysrq-trigger可模拟系统崩溃;强制重启命令echo b > /proc/sysrq-trigger会立即重启系统且不保存数据。
    • 死机场景模拟:执行上述命令后系统完全无响应,必须强制重启,且非正常关机可能导致日志无法完整写入磁盘。

(三)开机生效问题

  • 服务脚本:在/etc/systemd/system/[service].service.d/目录下创建conf文件。
  • 执行时机:使用ExecStartPost参数确保服务启动后执行设置命令。
  • 优势:相比rc.local更可靠,服务重启后设置依然有效。

(四)应用案例

  1. 例题:内存优化设置
    • 关键步骤:确定服务进程ID,修改oom_adj值为-17,通过systemd服务配置实现持久化。
    • 验证方法:查看/proc/[pid]/oom_score确认优先级,模拟内存压力测试观察进程是否被杀死。

三、内存泄露

(一)内存泄露概念

  • 定义:应用程序未能正确释放已分配的内存。
  • 典型表现:程序运行时占用内存持续增长,重启后恢复正常。
  • 危害:长期运行会导致系统性能下降甚至崩溃。

(二)检测工具

  1. valgrind:Linux系统自带的内存调试工具,检测原理是跟踪程序内存分配和释放操作,典型场景是开发人员用于检测代码中的内存管理问题。
  2. 其他内存检查工具
    • 工具安装:使用光盘自带的y-tools=memory check工具包进行安装。
    • 基本检测:执行命令ls可查看内存使用汇总,正常情况下应显示"没有内存泄露";通过运行big memory 512M程序模拟内存泄露场景,该程序会产生进程ID(如3438)。
    • 内存泄露分析:工具会显示"可能的丢失"提示,如检测到139KB内存泄露;字节数除以1024可转换为KB单位(如139KB);正常程序运行后应显示"没有内存线路",与异常程序形成对比。
    • 高级诊断参数:添加--track-origins=yes参数可精确定位到源代码问题行(如309行);注意程序文件可能带有特殊权限(如sui ds gid),需使用chmod修改权限才能执行;编译后的程序可通过/usr/share/doc/big_memory/src路径查找对应源代码。
    • 运维注意事项:运维人员只能检测内存泄露,修复需开发人员修改代码(如309行的vg_reply函数);内存泄露会导致程序反复异常,仅靠kill命令无法彻底解决问题;应针对持续占用资源异常的特定进程进行检查,而非全系统扫描。

四、应用案例

(一)共享内存与内存优化

  1. 共享内存基础概念
    • 定义:共享内存是多个应用程序可以共享同一段内存的机制,在数据库中使用特别频繁(如Oracle、MySQL等)。
    • 实现方式:通过内核参数设置,主要参数包括kernel.shmmaxkernel.shmall等。
    • 数据库应用:Oracle数据库通过共享内存实现SGA(System Global Area)系统全局区域,一个SGA对应一个共享内存段。
  2. 共享内存关键参数
    • shmmax:单个共享内存段的最大大小(单位:字节)。
    • shmall:系统中总共可分配的共享内存页数(单位:页)。
    • shmmni:系统支持的最大共享内存段数量(默认4096个)。
    • 参数关系:类比"土地管理"概念 - 有多少块地(shmmni)、每块地多大(shmmax)、总共能分配多少资源(shmall)。
  3. 实际调优案例
    • 问题现象:DB2数据库内存持续增长,系统运行523天后内存使用26GB/32GB,swap使用18GB/32GB。
    • 诊断过程:使用top命令发现db2cc进程占用40GB虚拟内存,pmap命令分析内存使用情况,发现shm(共享内存)占用过高,检查发现shmall参数被设置为16777216页(约64GB)。
    • 解决方案:调整共享内存参数,降低shmall值,使系统能及时释放不常用的缓存数据。
  4. 内存与磁盘互换技术
    • swap交换空间:原理是当内存紧张时,将硬盘空间临时充当内存使用,本质不提升性能,仅防止内存溢出;监控命令toppssar等可查看进程内存和CPU占用。
    • tmpfs内存文件系统:原理是将内存当作磁盘使用来提升写入性能(特别是随机小IO场景),内存速度是硬盘的10倍,适合缓存服务器等场景。
    • 应用案例:Squid代理服务器缓存目录挂载到tmpfs,Spark内存计算框架的过程数据存储。
    • 配置方法:默认大小为内存一半,重启后数据丢失,可通过/etc/fstab永久配置。
  5. 性能对比实验
    • 硬盘写入测试:速度约5.1MB/s(200MB数据耗时约40秒)。
    • 内存写入测试:速度约649MB/s(200MB数据耗时约0.3秒)。
    • 监控方法:通过free命令观察共享内存变化(写入后shmem从16MB增至216MB)。

五、非一致性内存访问

(一)一致性内存访问

  • 定义:传统架构中CPU通过前端总线(FSB)与内存通信,所有CPU访问内存的延迟相同。
  • 特点:数据必须调入CPU才能处理(如计算1加到100=5050);内存作为非持久化存储设备,在硬盘和CPU间起缓冲作用;遵循冯·诺依曼架构设计。
  • 瓶颈:当CPU核心数增加(如28核56线程)时,前端总线成为性能瓶颈。

(二)非一致性内存访问的发展

  • 解决方案:NUMA架构将CPU和内存分组为多个node,每个node包含若干CPU和本地内存(如4个node,每个含48个处理器),程序优先使用本地node资源。
  • 城市分区类比:类似武汉分武昌区、洪山区等行政区,办身份证只需去所在区政务中心,无需全市集中办理。
  • 优势:减少总线通信压力,遵循就近访问原则(内存访问距离:本地node=10,远程node=21)。

(三)numa命令

  • 查看命令numactl --hardware,可显示各node的CPU数量、内存使用情况以及输出距离矩阵(如node0到node0=10,node0到node1=21)。
  • 拓扑特点:全互联架构(任意node间可直接通信),远程访问距离相等(所有跨node访问均为21)。
  • 资源调度:系统监控各node剩余内存,本地资源不足时自动选择空闲最多的远程node。

(四)虚拟化内存复用

  • 华为FusionComputer实现:创建集群时可开启"内存复用"开关,关闭时虚拟机总内存≤物理内存(如256G),开启时允许超额分配内存。
  • "虚拟机NUMA结构自动调整"功能:开启后尽量将虚拟机的CPU和内存分配在同一node,未指定时自动均衡分布在各node。
  • 应用场景选择:需要低延迟时集中分配在单个node,需要高吞吐时均衡分布在多个node。
http://www.dtcms.com/a/340873.html

相关文章:

  • 对称加密算法
  • 数据库DML语言(增、删、改)
  • 闪电赋能全链路:领码SPARK一体化创新平台
  • 基于HTTP3的WebTransport实践
  • 基于 Java 和 MySQL 的精品课程网站
  • 在完全没有无线网络(Wi-Fi)和移动网络(蜂窝数据)的环境下,使用安卓平板,通过USB数据线(而不是Wi-Fi)来控制电脑(版本2)
  • Ubuntu 重连usb设备(断电和不断电方案)亲测可行
  • 亚马逊新品爆单策略:从传统困境到智能突破
  • LeetCode热题100--101. 对称二叉树--简单
  • C++ 力扣 438.找到字符串中所有字母异位词 题解 优选算法 滑动窗口 每日一题
  • 《数据之舞》
  • GitHub宕机生存指南:从应急协作到高可用架构设计
  • QT-图像灰度处理时QImage.setPixel方法存在的坑
  • 在QT中动态生成控件造成界面卡顿时的鼠标处理
  • Qt设置软件使用期限【新版防修改系统时间】
  • 一个 WPF 文档和工具窗口布局容器
  • GitHub宕机应急指南:无缝协作方案
  • Eclipse 里Mybatis的xml的头部报错
  • 软考高级--系统架构设计师--案例分析真题解析
  • Java项目基本流程(五)
  • DeepSeek API 申请与 Node.js 对接指南
  • 服务器硬件电路设计之 SPI 问答(一):解密 SPI—— 从定义到核心特性
  • 服务器硬件电路设计之 SPI 问答(三):SPI 信号完整性守护与时钟频率的硬件设计羁绊
  • PCL+Spigot服务器+python进行MC编程2(使用RCON)---可以生成角色
  • 图论Day6学习心得
  • 源码编译部署 LAMP 架构详细步骤说明
  • 算法第五十二天:图论part03(第十一章)
  • 《算法导论》第 34 章 - NP 完全性
  • HTTP的协议
  • 【爬虫实战-IP代理的重要性二】 以Selenium为例