尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
银河麒麟V10内存不释放的根因分析与定时清理方案
简介这份资料面向银河麒麟V10系统运维人员解决服务器长期运行中内存不释放、可用内存逐渐减少导致的性能下降问题。包内提供一套轻量定时处理方案RAR压缩包共3个文件含2个shell脚本和1个txt配置说明文档脚本可用于自动化监控与释放内存说明文档则交代部署和调整要点整体仅2KB易于下载后直接按需修改。已有780人学习下载适合需要快速缓解内存泄漏或临时回收内存的初中级运维者。通过阅读脚本与配置说明读者可结合free、top等命令掌握内存使用观察方法并据此设置定时任务、调整执行频率或阈值形成可持续的内存管理习惯。对于暂无法定位代码级泄漏的场景该方案能提供实用兜底手段降低系统卡顿与宕机风险。1. 银河麒麟V10内存不释放一个让运维凌晨三点爬起来的玄学问题在国产化服务器上跑业务我接手过一台银河麒麟V10的机器现象非常典型free -h 看 used 一天比一天高top 里看不到哪个进程特别离谱服务也还在可系统就是慢慢被拖到卡死最后某天凌晨业务进程直接消失查 dmesg 才发现是 OOM 把进程杀了。更折腾的是手动 drop_caches 或者重启应用内存能好一阵子过几天又涨回来像是系统自己把内存“吃”了不吐。这类问题在国产化替代的服务器上尤其多因为很多迁移过来的老业务没有完整的监控体系等看到告警时往往已经晚了。本文就用我实际处理过的一套定时清理方案把这台机器“内存不释放”的根因、排查顺序、脚本和坑全部梳理一遍新手可以直接抄脚本跑起来熟手能从我踩过的坑里拿走排查思路。2. 内存不释放的真相先分清 buffer/cache 和进程 RSS再谈清理2.1 看内存只看 used 是最大的错觉很多人一登录服务器就敲 free -m看到 used 那一列飙到 90% 就慌了马上想清理。问题在于银河麒麟V10 的 free 输出里used 是包含 page cache 的。内核为了提高 IO 性能会把读过的磁盘块、文件内容缓存到内存里这部分叫 Cached 和 Buffers本质上是“可以随时回收”的。真正需要关心的指标是 available也就是“在不触发 swap 的前提下还能分配给新进程的内存”。我处理那台机器时第一眼看到 used 93%但 available 还有 20%说明系统并没有那么紧张B 同学直接执行 echo 3 /proc/sys/vm/drop_caches把整台机器的 cache 全部清掉结果可用内存是降下来了可业务 IO 直接冲高数据库查询慢了一倍多。从那以后我要求团队先看 available再决定动不动手。判断内存是否真的“不释放”正确姿势是读 /proc/meminfo 的几个关键字段MemTotal、MemFree、MemAvailable、Buffers、Cached、SReclaimable、Writeback。其中 MemAvailable 才是内核根据内存碎片、回收压力动态计算出来的“真实可分配量”。如果 available 长期低于总内存的 10%才叫内存吃紧如果只是 Cached 高那是正常的系统行为。2.2 三种常见的病根cache 未回收、内存碎片、进程泄漏银河麒麟V10 上“内存不释放”本质上有三种原因三种的排查方向和清理手段完全不同。第一种是 page cache 回收不及时典型特征是 MemFree 低、MemAvailable 也低、Cached 高、Writeback 不为 0。这通常是因为磁盘写回慢脏页堆积占用了大量内存。第二种是内存碎片内核的伙伴系统分配不出大块连续内存但小块内存还有很多剩余这种在 /proc/buddyinfo 里一眼能看出来——order 为 0、1 的空闲块很多order 3 以上的大块几乎没有。碎片问题用 drop_caches 也没用因为它不整理伙伴系统。第三种是进程内存泄漏特征是某几个进程的 RSS 随时间持续增长重启进程后内存明显下降过一阵又涨回去。定位泄漏要观察单进程趋势不能只看全局。我遇到过一台跑 Java 服务的机器堆外内存一直在涨全局看 used 高但 Cached 不高、available 极低ps aux --sort-%mem 一看某个 Java 进程 RSS 已经占了一半内存重启进程后半小时内存又拉满最后定位到是 JNI 层没释放内存。遇到这种情况定时清理只能作为止血手段真正的解法是让开发改代码。3. 定时清理落地crontab 水位监控脚本给内存装上自动阀门3.1 第一步写一个只看 RSS 和 available 的监控脚本我习惯把清理脚本放在 /usr/local/sbin/ 下用 root 身份运行逻辑分两层先检测系统整体水位再检测具体进程的 RSS。如果整体 available 低于阈值就记录 top 内存进程如果某个白名单外的进程 RSS 异常增长就重启它。不要把“全局 used 高”当成杀进程的依据否则会误伤。下面这个脚本是我实际在银河麒麟V10上跑过一段时间的版本删掉了具体的业务进程名保留通用部分。#!/bin/bash # 内存水位监控与自动清理脚本适用于银河麒麟V10 # 放在 /usr/local/sbin/mem_watch.sh确认有执行权限后由 crond 调用 MEM_FILE/proc/meminfo LOG_FILE/var/log/mem_watch.log WARN_PCT85 # MemAvailable 低于 15% 时触发记录 RESTART_PCT92 # MemAvailable 低于 8% 时触发重启动作 # 读 MemTotal 和 MemAvailable单位都是 kB total$(awk /MemTotal/ {print $2} $MEM_FILE) avail$(awk /MemAvailable/ {print $2} $MEM_FILE) # 整数运算避免浮点比较在不同发行版上的兼容性问题 used_pct$(( (total - avail) * 100 / total )) echo $(date %F %T) used_pct${used_pct}% total_kb${total} avail_kb${avail} $LOG_FILE if [ $used_pct -ge $RESTART_PCT ]; then echo --- $(date %F %T) 内存紧张记录 top 进程 --- $LOG_FILE ps aux --sort-%mem | head -n 20 $LOG_FILE # 白名单只处理确定可以安全重启的业务服务 # 启动命令按实际环境修改tt --restart 是模拟重启动作 for svc in biz-web biz-api; do if pgrep -f $svc /dev/null; then /usr/bin/systemctl restart $svc echo 已重启 $svc $LOG_FILE fi done elif [ $used_pct -ge $WARN_PCT ]; then echo --- $(date %F %T) 达到警戒线只记录不重启 --- $LOG_FILE ps aux --sort-%mem | head -n 10 $LOG_FILE fi脚本先用两个 awk 分别从 /proc/meminfo 里提取 MemTotal 和 MemAvailable这一步不能用 free -m 解析因为 free 的输出在不同版本里列位置会变生产脚本里解析 free 是自找麻烦。这里所有判断都用整数 kB 计算 used_pct好处是 shell 的算术扩展不依赖 bc 或 awk 的浮点能力银河麒麟V10 默认安装的 mawk 在某些版本上浮点比较会静默出错。WARN_PCT 和 RESTART_PCT 两个阈值根据机器实际内存调整我一般建议 4GB 内存的机器警戒线放低一点内存大于 32GB 的机器可以适当调高。脚本最关键的设计是“只重启白名单服务”宁愿漏杀也不要错杀后面避坑章节我会专门讲误杀事故。3.2 第二步crontab 配置要避开环境变量这个大坑脚本写好之后测试执行一遍确认没有报错然后交给 crond。crontab 里有两处容易翻车一是 crond 默认 PATH 很精简脚本里如果用了 /usr/bin 之外的工具或者脚本本身没有写绝对路径就会静默失败二是 crond 不是登录 shell不会加载 /etc/profile 里的环境变量如果脚本依赖了 JAVA_HOME 之类的变量直接跑没问题放进 cron 就找不到命令。我的做法是脚本内部全用绝对路径systemctl、pgrep、awk 都写全路径crond 配置里显式指定 SHELL 和 PATH。# crontab -e 追加每 5 分钟执行一次内存水位检查 SHELL/bin/bash PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin */5 * * * * /bin/bash /usr/local/sbin/mem_watch.sh /var/log/mem_watch_cron.log 21第 1、2 行是给 crond 用的环境变量保证脚本运行时能用到正确的 bash 和基础命令路径。第 3 行是定时规则*/5 表示每 5 分钟跑一次。这里我刻意选了 5 分钟而不是 1 分钟因为内存增长是慢过程1 分钟跑一次除了刷日志没意义还会在内存峰值时叠加脚本自身的开销。日志重定向到独立文件避免和脚本内部日志混在一起排查 crond 问题时可以分开看。注意脚本本身必须用 chmod x 加上执行权限否则 crontab 会报 “No such file or directory”并不是脚本不存在而是没权限执行。3.3 第三步drop_caches 到底该不该用什么时候用很多网上的教程会让你执行 echo 3 /proc/sys/vm/drop_caches说能“清空缓存释放内存”。这个命令在银河麒麟V10 下确实有效但我强烈建议只在两种场景使用一是确认 available 已经极低且进程 RSS 都不高说明内存被 cache 占满这时可以清二是在业务低峰期例行维护时为了给即将上线的批量任务腾内存。drop_caches 的写法有讲究参数 1 只释放 page cache参数 2 释放 dentries 和 inodes参数 3 是两者都清。生产环境我会先用 1不要一上来就 3因为清 dentries 会让文件系统元数据重新加载对大量小文件的业务影响很明显。实际执行前强制刷盘是必须的sync echo 1 /proc/sys/vm/drop_caches cat /proc/sys/vm/drop_cachessync 先确保脏页写回磁盘避免丢数据echo 1 只清 page cache保留 dentries最后的 cat 只是确认值写入成功。我遇到过一次执行 echo 3 之后某个 Java 应用访问大量小配置文件每次 stat 都重新读磁盘接口延迟从 8 毫秒涨到 200 多毫秒从那以后我再也没有默认用 3。如果你把它放进定时脚本还要加一个条件判断只有 available 低于阈值时才执行不能每次 crontab 触发都清。更好的替代方案是调低 /proc/sys/vm/vfs_cache_pressure让内核更积极回收缓存而不是手动粗暴清理。4. 进程被 OOM 杀掉之后先捞现场再决定重启还是扩容4.1 从 dmesg 和 journald 里找回被杀进程的现场OOM 是比内存不释放更严重的结果说明定时清理也没能及时止住。银河麒麟V10 的内核在触发 OOM 时会把“谁被杀了、当时内存状况如何”写进内核日志。我最常用的捞现场命令是 dmesg因为 OOM 信息会保留到下次重启journald 在某些裁剪版系统上可能没有完整落盘dmesg 更稳。dmesg -T | grep -i -B 2 -A 8 out of memory journalctl -k -T --since 1 hour ago | grep -i -A 8 oom-kill cat /var/log/messages | grep -i -B 2 -A 8 oom第一条直接搜内核环形缓冲区里的 OOM 记录-B 2 带出触发前两行上下文-A 8 显示被杀的进程名、PID、RSS 和当时的全局内存水位。第二条是查看 systemd 的 kernel 日志适合 dmesg 输出被别的内容刷掉时用。第三条是保守方案/var/log/messages 在很多系统上还在写。我实际遇到的情况是 dmesg 里明确写了 “Killed process 13245 (biz-java), total-vm:8543200kB, anon-rss:4100000kB”说明是 Java 进程的匿名页占满了内存。注意不要只看进程名就完事还要看是哪个 cgroup 触发的 OOM如果 OOM 发生在 systemd slice 里说明是服务本身的 MemoryLimit 设置太保守而不是整机内存不够。4.2 Overcommit 和 min_free_kbytes改内核参数防止频繁误杀捞到现场之后如果不做任何调优过几天同样的 OOM 还会再来。我一般会顺手检查 /proc/sys/vm/overcommit_memory 和 /proc/sys/vm/min_free_kbytes。overcommit_memory 默认是 0也就是启发式过度分配部分应用申请内存时会预支如果被改成了 1内核几乎不做任何检查就直接分配等到物理内存耗尽时再来 OOM这会让定时清理脚本根本来不及反应。min_free_kbytes 则决定内核为紧急分配保留多少内存默认值太小的话系统在内存耗尽前不会主动回收。这两个参数不建议在生产环境乱改但有一个场景我几乎必改数据库或缓存类服务对延迟敏感需要把 OOM 的触发点尽量延后给运维留出人工介入时间。落地写法是在 /etc/sysctl.conf 里追加配置再 sysctl -p 生效# 保留更多紧急内存防止系统在内存耗尽前毫无还手之力 vm.min_free_kbytes 1048576 # 保持默认的启发式 overcommit不强制关闭 vm.overcommit_memory 0 vm.swappiness 10vm.min_free_kbytes 设成 1GB适合 16GB 以上的机器内存小的机器设置这么大会白白浪费可用内存。swappiness 降到 10 是让内核尽量少用 swap优先回收内存。这些参数不是万能药但配合定时清理脚本一起用能把 OOM 概率大幅压低。如果业务确实需要超大虚拟内存那就别靠内核参数硬撑老老实实加物理内存或者拆分服务。5. 避坑与常见问题定时清理方案里的五个坑我全踩过5.1 现象crontab 里写了脚本但它一次都没跑原因排查crond 服务没启动、脚本没有执行权限、脚本内部用了相对路径。我踩的坑是脚本里写了 top -b -n 1而 top 在精简版系统上不存在cron 日志里看到 “command not found”但 crond 本身是好的。解决systemctl status crond 确认服务在跑然后直接用 /bin/bash 调用脚本脚本内部所有外部命令都用绝对路径运行时把 stdout 和 stderr 都重定向到日志。验证方式很简单在 crontab 里临时加一条每分钟执行 date 的命令看 /var/log/cron 有没有记录就能确认 crond 链路是否正常。5.2 现象脚本里的 awk 浮点比较在银河麒麟V10 上报错或者结果不对原因系统默认的是 mawk对浮点精度支持不好用 awk BEGIN{print 1.1 1.0} 这类判断在某些版本上会静默输出错误结果。解决不搞浮点全部换算成整数再比较。我在脚本里用 used_pct$(( (total - avail) * 100 / total ))纯 shell 整数运算避免 awk 参与大小判断。如果你确实需要算百分比用 bc 也可以但 bc 不一定默认安装为了一个百分比去额外安装软件包不值得。5.3 现象脚本把 sshd 或者其他关键进程给杀了远程直接断掉原因auto-kill 逻辑里用了 pgrep 模糊匹配pgrep -f ssh 会把 sshd、sshd-agent 全部匹配进来误杀后远程连接全部断开。解决白名单机制只对明确写出的服务名执行重启再加一个保护判断禁止对 PID 为 1 的进程以及 sshd、crond 执行任何 kill 动作。我的脚本里不会写“谁内存高就杀谁”只写“白名单内的服务内存超限就重启”宁可漏掉泄漏进程也不能误杀无辜。还有一个细节重启服务之前先检查它是不是 systemd 管理的如果服务不是 systemd 启动的systemctl restart 会报错要改用 kill 原启动命令拉起。5.4 现象/proc/meminfo 的数单位搞错脚本算出来的百分比完全错误原因/proc/meminfo 里的 MemTotal、MemAvailable 单位是 kB有人把它当成字节来算然后跟 free -m 对比发现对不上就怀疑脚本有问题。解决全链路统一用 kB 计算只有输出给人类看时才转成 MB 或 GB。我脚本里的 total_kb 和 avail_kb 就是这种思路日志里记录单位不会出现“30561MB”这种混用。特别注意/proc/meminfo 的数值都是按 1024 进制的不是 1000写死倍数时不要用字节除以 1000。5.5 现象定时执行 echo 1 drop_caches 之后业务查询反而变慢原因cache 冷启动。page cache 被清掉后所有原来命中缓存的文件读取全部穿透到磁盘尤其对数据库类业务缓冲池的 page 重新加载需要时间。解决不要把 drop_caches 当成常规定时任务只在 available 低于阈值时应急触发优先调高 vfs_cache_pressure 让内核主动回收如果业务是数据库可以用数据库自己的内存管理参数例如 MySQL 的 innodb_buffer_pool_size没必要靠操作系统清理缓存来腾内存。这个坑本质上是“把 cache 高当成内存不释放”的错误认知导致的回到第 2 章的判断方法先确认 available 真的低再考虑清理。6. 快速定位内存不释放一套黑匣子排查顺序三十秒分清类别6.1 三步定位法接到告警之后不要先看监控大盘直接登录服务器按下面顺序执行。第一步free -h 看 available第二步ps aux --sort-%mem | head -n 10 看是谁占了进程内存第三步cat /proc/meminfo 看 Cached 和 Writeback。这三步能筛掉九成误判顺序不要反先看全局再看局部才能避免把 cache 当泄漏。定位结果对照available 低但 Cached 高是缓存回收问题available 低且单个进程 RSS 高是泄漏available 低且 buddyinfo 大块空闲少是碎片。碎片问题再执行一条 grep -A 5 Node /proc/buddyinfo如果 order 3 以上基本为 0那就是碎片这种用 None 解决不了要么重启服务要么让内核做内存规整echo 1 /proc/sys/vm/compact_memory不过对正在跑的生产环境我不建议手动 compact。6.2 验证定时清理是否生效脚本上线之后至少观察三天重点看 /var/log/mem_watch.log 里每天的内存趋势以及 /var/log/cron 里有没有报错。我的习惯是把日志按周切割如果内存使用率曲线没有持续抬升说明方案生效如果每周水位都在缓慢上涨说明泄漏源头没堵住定时清理只是拖延了 OOM 的发生时间必须回去查具体进程。从那以后我每次接内存告警都是先 free -h再 ps 排 RSS把 cache 和泄漏分开想清楚再动刀踩过的这些坑基本没再翻过车。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

Qt雷达图实现:极坐标扫描与余晖动效的 QPainter 实战

Qt雷达图实现:极坐标扫描与余晖动效的 QPainter 实战

简介:本资源是一套基于Qt 5.9实现雷达图(卫星图)与余晖扫描动态效果的完整C工程,面向具备Qt基础的中高级GUI开发学习者及嵌入式可视化项目开发者,解决多维数据动态可视化、雷达风格交互图表定制等实际需求。压缩包共53…

📅 2026/10/16 13:44:35
语音风格迁移落地实践:从特征解耦到韵律建模

语音风格迁移落地实践:从特征解耦到韵律建模

语音风格迁移这几年在行业里突然变得很常见,但我真正动手做完第一版 demo 之后,最大的感受是:这个词被高估了。大多数人以为它就是“换音色”,或者“复刻某人的语气”,实际上它是一组任务的总称,背后涉及特…

📅 2026/10/16 13:44:35
官宣AI生成引擎的同一天,REDox开源:卡普空这步棋你看懂了吗

官宣AI生成引擎的同一天,REDox开源:卡普空这步棋你看懂了吗

官宣AI生成引擎的同一天,REDox开源:卡普空这步棋你看懂了吗 【免费下载链接】REDox High-performance, token-based structured data engine for .NET. A core component of REX, the technology behind CAPCOMs next-generation game engine. 项目地址…

📅 2026/10/16 13:44:35
MORE NEWS

更多资讯

📰

视觉SLAM框架入门:四模块协同与工程落地关键点

1. 项目概述:为什么“视觉SLAM框架”是入门者最该啃下的第一块硬骨头刚接触机器人、自动驾驶或AR开发的朋友,常会听到一个词:SLAM。它像一道门槛,横在“能跑demo”和“真懂系统”之间。而视觉SLAM——用普通摄像头替代激光雷达做同…

📰

VoLTE掉话根因定位与三层协同优化实战

简介:本资源是一份面向4G VoLTE网络优化工程师与通信运维人员的实战型掉话问题分析指南,聚焦中兴eNodeB设备在VoLTE业务中高频发生的异频/异系统重定向、TM3/TM8模式转换、X2接口配置及RLC优先级等典型掉话根因。文档基于广州ATU网格真实优化案例&#x…

📰

OpenClinica语言包中文本地化:结构解析、编码处理与自动化校验

简介:OpenClinica语言包是面向临床研究信息化人员、EDC系统管理员及本地化开发者的多语言适配资源,用于解决开源电子数据采集系统OpenClinica界面本地化不足的问题。包内共85个文件,以83个properties翻译资源文件为主,覆盖admin、…

📰

D-Bus 深度解析:从源码编译、总线机制到实战排错

1. 项目概述:为什么今天还要深挖 D-Bus? D-Bus 不是新词,但“D-Bus 详解:从编译到应用”这个标题背后藏着一个被严重低估的现实——* 绝大多数 Linux 桌面开发者、系统工具编写者,甚至不少嵌入式中间件工程师&#x…

📰

上海五期医保接口HIS对接全解析:从交易链路到踩坑实战

简介:面向医院HIS系统开发与运维人员的上海医保五期接口说明文档,聚焦医保中心与HIS之间的数据交互,系统讲解电子凭证解码、医保项目明细上传、挂号收费、住院结算、对账退款等核心接口的调用方式。文档共三章:引言部分梳理目的、…

📰

CXL 2.0深度解析:内存所有权重构与缓存一致性设计

简介:CXL 2.0协议规范中文版是一份面向数据中心高性能互连设计的技术文档,由开放标准组织CXL联盟推动,并得到Intel、AMD、NVIDIA、IBM等厂商支持,可供处理器/加速器架构师、FPGA开发者及从事内存扩展和缓存一致性研究的工程师参考…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬