生产环境内存使用率 95%+:原因排查 + 分步解决方案
目录一、先区分是系统内存满还是应用进程内存满1. 查看整机内存Linux2. 定位占用最高的进程二、常见原因分类 对应排查场景 1Linux 系统层面内存高非应用泄漏原因 1Linux 文件缓存buff/cache占用高原因 2僵尸进程 / 孤儿进程、残留后台进程原因 3系统内核、驱动、定时任务异常场景 2中间件 / 数据库占用内存过高高频1. MySQL2. Redis3. Elasticsearch场景 3Java 应用内存爆满最主流业务场景常见根因分步排查命令JavaJava 快速解决场景 4Docker / K8s 容器内存满三、标准处理流程生产上线直接套用第一步紧急止血内存 95%业务即将宕机第二步定位根因必做防止复发第三步根治优化长期方案四、快速自查清单一分钟自检先分系统层、应用层、JVM / 容器层三大类定位问题再按「紧急止血→根因排查→根治优化」处理覆盖 Linux 服务器、Java 应用、容器 (K8s/Docker) 主流场景。一、先区分是系统内存满还是应用进程内存满登录服务器执行基础命令第一步定性1. 查看整机内存Linuxfree -htotal总内存used已使用内存buff/cache页缓存、文件缓存可回收不算真正泄漏available真实可用内存核心指标关键判断available 很低整机内存真吃满业务 / 系统占用过高used高但available充足只是系统缓存多无需处理2. 定位占用最高的进程# 按内存排序看TOP进程 top -o %MEM # 或简洁版 ps aux --sort-%mem | head -10记下PID、进程名Java/Go/ 数据库 / 中间件等。二、常见原因分类 对应排查场景 1Linux 系统层面内存高非应用泄漏原因 1Linux 文件缓存buff/cache占用高Linux 会尽量利用空闲内存做磁盘 IO 缓存读写文件越多缓存越大表象内存 90%但available正常。特征业务无卡顿、无 OOM、无服务宕机负载平稳临时清理仅应急不建议频繁操作# 清理页缓存生产慎用会短暂IO抖动 echo 1 /proc/sys/vm/drop_caches根治无需根治这是 Linux 正常机制内存本就该被利用。原因 2僵尸进程 / 孤儿进程、残留后台进程大量失效进程占用堆内存、句柄。 排查ps -ef | grep defunct # 查看僵尸进程处理找到父进程重启 / 杀掉清理残留进程。原因 3系统内核、驱动、定时任务异常crontab 疯狂执行脚本、日志轮转异常、内核 BUG、挂载大文件等。 排查crontab -l # 查看定时任务 df -h du -sh / # 检查磁盘、大文件 dmesg -T # 查看内核报错、OOM killer日志场景 2中间件 / 数据库占用内存过高高频生产最常见MySQL、Redis、Elasticsearch、MQ、Nginx 等中间件吃满内存。1. MySQL原因innodb_buffer_pool_size设置过大超过服务器物理内存连接数过多、慢查询、临时表 / 排序区暴涨。排查show engine innodb status;、查看连接数、慢日志解决buffer_pool 建议设为物理内存 50%~70%单机 MySQL集群下调低优化慢 SQL、索引、大事务限制最大连接数2. Redis原因maxmemory未配置、海量大 Key、热 Key、持久化 (RDB/AOF) fork 子进程占用内存、内存淘汰策略失效。排查info memory、redis-cli --bigkeys解决配置maxmemory 合理淘汰策略allkeys-lru拆分大 Key、过期无用数据、限制客户端连接3. Elasticsearch原因JVM 堆设置过大、分片过多、查询聚合语句炸内存、内存锁定开启。解决ES 堆不超过 31G优化 DSL 语句、合理规划分片。场景 3Java 应用内存爆满最主流业务场景进程为java/javac内存持续上涨、触发 OOM、GC 频繁。常见根因内存泄漏代码问题内存只涨不跌JVM 堆参数设置不合理堆太大 / 太小堆外内存泄漏Netty、NIO、JNI、第三方 SDK频繁创建大对象、大集合接口批量查数据不分页线程数爆炸、线程栈溢出分步排查命令Java查看 JVM 整体状态jstat -gc PID 1000 # 每秒打印GC情况看FGC次数、堆使用率频繁 Full GC、堆内存使用率逼近最大值 → 堆溢出 / 泄漏导出堆快照生产优先在线排查再 dump# 生成堆dump大文件选业务低峰 jmap -dump:formatb,fileheap.hprof PID用MAT/VisualVM分析查找大对象、死集合、静态集合无限持有对象定位泄漏类、泄漏代码行排查堆外内存Netty 应用重点# 查看进程虚拟内存、物理内存 cat /proc/PID/status | grep Vm堆外高检查 Netty 内存池、第三方 SDK、文件流未关闭。Java 快速解决临时应急重启应用最快降内存治标调整 JVM 参数根据服务器内存合理配置 示例8C16G 服务器单机 Java 应用-Xms8g -Xmx8g # 堆固定大小避免扩容抖动 -XX:MaxDirectMemorySize2g # 限制堆外内存代码修复集合使用后清空、避免静态 List/Map 无限累加接口分页禁止全表查询关闭流、连接、上下文try-with-resources修复循环引用、匿名内部类持有外部对象场景 4Docker / K8s 容器内存满容器内内存 95%分为容器限制不足和容器内应用泄漏。查看容器内存限制与使用docker stats # 进入容器内部排查 docker exec -it 容器ID free -h原因容器memory limit设置过小业务量上涨后不够用容器内应用本身内存泄漏同 Java / 业务代码问题容器日志打满、日志文件不轮转解决合理调高容器内存配额配置容器日志轮转避免日志占内存 / 磁盘进容器内部按上面「应用排查」定位代码问题三、标准处理流程生产上线直接套用第一步紧急止血内存 95%业务即将宕机先看free -hdmesg确认是否被系统 OOM 杀进程若应用进程占比最高低峰重启对应服务快速释放内存若缓存过高按需执行缓存清理业务低峰操作临时扩容服务器 / 容器内存临时扛流量第二步定位根因必做防止复发区分系统缓存 / 中间件 / 业务应用 / 容器应用类抓 GC 日志、堆 dump、线程栈分析泄漏点中间件类检查配置、慢查询、大 Key、连接数系统类检查定时任务、大文件、内核日志第三步根治优化长期方案配置优化JVM / 中间件内存参数合理化不超物理内存容器资源配额、日志轮转、连接池上限收紧代码优化修复内存泄漏、批量接口分页、关闭资源句柄优化大对象、循环逻辑、静态集合架构优化大服务拆分为微服务分散内存压力热点数据做缓存、异步化减少内存常驻监控告警配置内存使用率告警阈值建议 80% 预警90% 紧急监控 GC、OOM、进程状态提前发现问题四、快速自查清单一分钟自检free -h→ available 是否充足top→ 哪个进程吃内存最多dmesg→ 有没有Out of memory: Killed processJava 应用jstat -gc→ 是否频繁 Full GC中间件Redis/MySQL/ES 内存配置是否超限容器是否配置了内存限制、日志是否爆了