在 CentOS(或其他 Linux 系统)上,Java 进程占内存“看起来很高”,通常不是真的“泄漏”,而是由 Java 的内存模型和 Linux 的内存统计方式共同造成的。下面按常见原因 → 说明 → 排查方法给你梳理。
Java 默认或你显式设置了:
-Xms2g -Xmx4g
那么 JVM 一启动就可能占用 2~4G 虚拟内存。
✅ 查看:
ps -eo pid,comm,vsz,rss | grep java
VSZ 很大是正常的(虚拟内存)RSS 才是真实物理内存Java 除了堆,还会用:
常见配置:
-XX:MaxMetaspaceSize=512m
如果没限制,可能慢慢涨。
每个 Java 线程默认栈大小:
-XX:ThreadStackSize=1m
如果有 1000 个线程 = 1GB 内存
查看线程数:
ps -eLf | grep java | wc -l
CentOS 中:
free -m 的 used 包含文件缓存free -h
重点看:
available
不同 GC 行为不同:
表现:
排查工具:
jstat -gcutil <pid> 1000
jmap -histo <pid> | head
Java 调用 free() 后:
表现:
可用:
MALLOC_ARENA_MAX=2 java ...
如果在 Docker:
解决:
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=75
✅ 正常:
❌ 异常:
java -X)free -h 输出ps 中 RSS 大小我可以直接帮你算 “内存到底花哪了”。