linux内存占用高需分层排查:先看free -h的available值判断真实可用内存,再用top/htop定位高res进程,接着检查shmem、sunreclaim、hugepages等内核内存项,最后对java应用用jstat、jmap和mat分析堆泄漏。

Linux内存占用过高,不能只看used高就断定“内存不够”,关键得区分是真实占用、缓存堆积,还是真正的内存泄漏。排查要分层推进:先看整体水位,再定位进程,最后深入内核或应用层确认是否泄漏。
第一步:看真正可用内存(别被 free -h 的 used 欺骗)
运行:free -h
重点盯住 available 这一列——它代表不触发 swap 时还能给新程序用的内存预估值。
如果 available ,且 swap used > 0 并持续增长,说明物理内存确实吃紧。
补充验证:cat /proc/meminfo | grep -i "memfree\|cached\|available"
对比 MemFree(纯空闲)、Cached(可快速回收的文件缓存)、MemAvailable(内核估算的真正可用值)。Cached 高但 MemAvailable 也充足,通常只是系统在“聪明地利用闲置内存”,不是问题。
第二步:揪出吃内存的进程(top/htop 是第一把刀)
运行:top → 按 Shift + M 按内存使用量降序排列
或直接用更友好的:htop(如未安装,sudo apt install htop 或 sudo yum install htop)
关注字段:
• RES:进程实际占用的物理内存(KB),最反映真实开销
• %MEM:占总物理内存的百分比
• COMMAND:进程名,注意是否有异常命名、重复实例或已知高内存服务(如 Java、数据库、缓存服务)
快速筛选前5名:ps aux --sort -rss | head -n 6
第三步:排除内核级干扰项(共享内存、slab、大页)
有些内存“看起来被占了”,实则不属于用户进程,需单独检查:
- 共享内存占用:
cat /proc/meminfo | grep -i shmem
若 Shmem 值异常高(比如几百MB以上),可能是 tmpfs 挂载点或 IPC 共享段未清理 - 不可回收 slab 内存:
cat /proc/meminfo | grep -i sunreclaim
SUnreclaim 持续升高,常见于内核模块泄漏、大量小文件缓存未释放 - 内存大页(HugePages):
cat /proc/meminfo | grep -iE "hugepages_total|hugepagesize"
若 HugePages_Total > 0,确认是否业务必需;否则建议禁用:
→ 注释/etc/sysctl.conf中的vm.nr_hugepages行
→ 执行sysctl -p
第四步:Java 应用内存泄漏专项排查(如适用)
若高内存进程是 Java 程序,按以下节奏判断是否泄漏:
- 先确认现象:
•jstat -gc <pid> 2000 5</pid>(每2秒采样,共5次)观察 old gen used 是否单向爬升,Full GC 后不回落
• 日志中频繁出现java.lang.OutOfMemoryError: Java heap space或GC overhead limit exceeded - 抓快照分析:
•jmap -dump:format=b,file=/tmp/heap.hprof <pid></pid>
• 或用 Arthas:arthas-boot.jar启动后执行heapdump /tmp/heap.hprof - 离线分析:
用 Eclipse MAT 打开 hprof 文件,查看 Leak Suspects Report 和 dominator tree,聚焦对象数量暴涨、Retained Heap 占比高的类










