需用shell脚本周期性监控java进程rss内存和jvm堆使用率,结合系统总内存动态设阈值(如rss>60%总内存且堆>75%),超限即邮件告警,并通过crontab每2分钟执行、加锁防重跑、日志同步至/var/log/messages。

Java 应用在 Linux 上长期运行时,内存泄漏或负载突增可能导致堆内存持续攀升,最终触发 OOM Killer 或服务假死。单纯依赖 JVM 参数(如 -XX:+HeapDumpOnOutOfMemoryError)不够主动——你需要在“逼近硬件极限”前就感知风险。核心思路是:**用 Shell 脚本周期性采集 Java 进程的 RSS 内存 + JVM 堆使用率,结合系统总内存做动态阈值判断,达标即发邮件**。
抓取真实内存占用(RSS + JVM 堆)
Java 进程的 ps aux 中的 %MEM 是相对系统总内存的百分比,但 RSS(Resident Set Size)才是实际物理内存占用,更可靠。同时,JVM 堆使用情况需通过 jstat 获取,避免只看 RSS 忽略元空间、直接内存等。
- 用
pgrep -f "your-app-name.jar"精准定位 PID(避免匹配到日志或 grep 自身) - RSS 获取:
ps -o rss= -p $PID 2>/dev/null | awk '{print int($1/1024)}'(单位 MB) - JVM 堆使用率:
jstat -gc $PID | tail -1 | awk '{printf "%.1f", ($3+$4)/$2*100}'(Eden + Survivor 占 Young Gen 比例,或用$3+$4+$10计算整个堆使用率) - 系统总内存:
free -m | awk 'NR==2{print $2}'
设定动态告警阈值(不硬编码 80%)
固定百分比(如 “内存 >80%”)在不同机器上意义不同。应按“进程 RSS 占系统总内存比例”+“JVM 堆使用率”双维度判断,并留安全余量:
- 例如:当
RSS > (系统总内存 × 0.6)且JVM 堆使用率 > 75%,说明应用已吃掉系统大部分内存,GC 压力大,风险高 - 也可加一条兜底规则:
RSS > 4000(MB),适用于内存 ≥16GB 的服务器,防止小内存机器误报 - 阈值写进脚本变量,方便运维按环境调整,不写死在 if 判断里
用 mailx 或 sendmail 发告警邮件(轻量可靠)
Linux 自带 mailx(需安装 mailutils 或 heirloom-mailx)即可发文本邮件,无需额外部署邮件服务:
- 配置 SMTP(以 Gmail 为例):
echo "set smtp=smtp://smtp.gmail.com:587" >> ~/.mailrc,并设置应用专用密码 - 发送命令示例:
echo "警告:Java 进程 $PID RSS=${rss_mb}MB,堆使用率 ${heap_pct}%,已超阈值" | mailx -s "[ALERT] Java 内存异常" admin@example.com - 邮件内容务必包含时间戳、PID、RSS、堆使用率、服务器 hostname,方便快速定位
用 crontab 实现每 2 分钟自动巡检
高频检测(如 30 秒)易造成资源扰动;太低频(如 10 分钟)可能错过峰值。2 分钟是平衡点:
- 编辑定时任务:
crontab -e - 添加行:
*/2 * * * * /path/to/check_java_mem.sh > /dev/null 2>&1 - 脚本开头加锁(
if [ -f /tmp/java_mem_check.lock ]; then exit; else touch /tmp/java_mem_check.lock; trap 'rm -f /tmp/java_mem_check.lock' EXIT;),防重复执行 - 每次执行完清理临时状态,避免锁残留
不复杂但容易忽略:告警后别只等邮件,建议脚本里加一句 logger "JAVA MEM ALERT: PID=$PID RSS=${rss_mb}MB HEAP=${heap_pct}%",把记录同步写入 /var/log/messages,和日志系统联动更稳。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











