当前位置: 首页 > java >正文

部署在linux上的java服务老是挂掉[排查日志]

最开始的时候,严重怀疑是内存不足导致的,但是一直没得排查,最近某个服务挂掉的几率越来越高了不得不排查一下。

先从jar自己打印的debug,error查起,发现在挂掉之前没有一点异常直接下一步(也没想着这里能查到什么)毕竟“启动成功、运行中突然挂,业务日志无异常”——99% 是进程被操作系统干掉或者 JVM 自己 Abort

直接上排查 "三部曲"

  • 确认“是谁”杀进程
  • 全局搜 JVM 崩溃日志
  • 看 GC 日志有没有“死循环”

1.确认“是谁”杀进程,看看是不是OOM Kill

什么是 OOM Kill ?

内核选择性杀掉某个进程来回收内存,这个过程叫 OOM Kill

直接输入下面的命令先查看

# 1. 系统日志里找 kill 记录
sudo journalctl --since "1 hour ago" | egrep -i "killed process.*java|oom-killer"

这个指令的意思是:

在系统日志(journal)里,搜索最近 1 小时内,涉及 Java 进程被杀掉或触发 OOM Killer 的记录。你可以通过修改journalctl --since "1 hour ago" 来实现查询更久之前的,我这里挂了就马上排查所有我只看1小时内的免得有其它影响

通过命令可以看到系统返回给我们的信息

答案已经呼之欲出了,警告信息:

Aug 13 14:21:32 VM-8-2-opencloudos kernel: sort invoked oom-killer: gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0, oom_score_adj=0 Aug 13 14:21:32 VM-8-2-opencloudos kernel: Out of memory: Killed process 1461612 (java) total-vm:3390404kB, anon-rss:755084kB, file-rss:12044kB, shmem-rss:0kB, UID:0 pgtables:1964kB oom_score_adj:0

看到Out of memory:就表示系统内存不够了

Killed process 1461612 (java):内核杀掉了 PID=1461612 的 Java 进程

果然,oom kill了,系统主动杀了一个占用内存大的进程,也就是挂掉的那个服务

所以 Java 应用会莫名其妙挂掉,也不会生成 JVM hs_err_pid.log,因为这是 操作系统级别的强杀,JVM 根本没机会写日志.

还有另一种方式,直接查看内核缓冲区日志,跟上面那个方式差不多

# 2. 内核环形缓冲区
dmesg -T | egrep -i "killed process|oom_reaper|segfault

从该指令返回的信息我们可以看到这几个时间都发生了 OOM Kill 都因为内存不足导致的

使用命令查看我们内存使用情况

free -h

逐项分析:(但是着重看 used 和 available)

total 3.6Gi

物理内存总容量:大约 3.6 GB(可能是 4GB 物理内存减去一些保留给内核/显存的空间)。

used 3.5Gi

当前已使用的内存(包含应用、缓存等)。

free 120Mi

完全空闲、未分配的内存(非常少)。

shared 3.4Mi

共享内存占用(主要是 tmpfs、shm)。

buff/cache 157Mi

文件缓存、缓冲区(可被回收)。

available 81Mi

系统真正还能分配给应用程序的内存:只有 81MB,这个值低到随时会触发 OOM。

我们还可以通过下面的指令查看是谁吃的内存这么多,我这里是这几个java服务吃最多,吃完了

# 按内存占用排序

ps aux --sort=-%mem | head -20

-----------------------------------------------------------------------

这种情况加内存是最有效的方式

但是,我还想挣扎一下,我决定做这两步:

1.打开Swap, 开 2G 的swap

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

开机自启 swap

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

2.限制开销不大的服务最大堆的空间

把512m 改成 256m

第一步排查就已经查到问题了,三部曲都没走完,但是不是每一个人都是这种情况,下面两部也简单说一下

2.全局搜 JVM 崩溃日志

如果你不是 oom kill 导致的,那么jvm可能在"临kill"前会给你留下线索

# 最近 7 天内所有 hs_err 文件

sudo find / -type f -name "hs_err*.log" -mtime -7 2>/dev/null

  • 文件名匹配模式,找类似 hs_err_pid12345.log 这样的文件。

  • 这些一般是 Java 虚拟机(JVM)崩溃时生成的错误日志,里面会有堆栈、CPU、内存等信息。

然后分析这些日志排查一下

3.看 GC 日志有没有“死循环”

如果你没有打开GC日志,那你得在jar包启动指令上面加上下面这个指令,下次复现时就能拿到日志了

JAVA_OPTS="$JAVA_OPTS -Xloggc:$APP_HOME/logs/gc_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"

等下次复现之后就可以输入下面的指令查看了

grep -c "Full GC" logs/gc_*.log

http://www.xdnf.cn/news/17786.html

相关文章:

  • 终端安全检测与防御
  • 5. synchronized 关键字 - 监视器锁 monitor lock
  • 2025年,Javascript后端应该用 Bun、Node.js 还是 Deno?
  • MyBatis-Plus 分页失效问题解析:@Param 注解的影响与解决方案
  • “我店模式”:零售转型中的场景化突围
  • 万字长文全解析:五种主流归一化方法深入讲解(BN/LN/IN/GN/WN)
  • 资源查看-lspci命令
  • React useMemo 深度指南:原理、误区、实战与 2025 最佳实践
  • Linux网络性能调优终极指南:深度解析与实践
  • pt-online-schema-change 全解析:MySQL 表结构变更的安全之道
  • Jenkins(集群与流水线配置)
  • 神经网络的核心组件解析:从理论到实践
  • Qt字符串与数值相互转换
  • 蓝桥杯备赛 按键、LCD、定时器
  • 面试实战 问题二十七 java 使用1.8新特性,判断空
  • 3.Ansible编写和运行playbook
  • 基于 MybatisPlus 将百度天气数据存储至 PostgreSQL 数据库的实践
  • k8s中的微服务
  • HTTP 请求转发与重定向详解及其应用(含 Java 示例)
  • 【Golang】 Context.WithCancel 全面解析与实战指南
  • model层实现:
  • CompletableFuture介绍及使用方式
  • Java多线程进阶-从乐观锁到读写锁
  • 网络安全和基础设施安全局 (CISA) 表示微分段不再是可选的
  • 基于UniApp的新大陆物联网平台温湿度检测系统开发方案
  • 基于机器学习的自动驾驶汽车新型失效运行方法
  • FPGA的PS基础1
  • 中科米堆CASAIM汽车零部件三维扫描检测解决方案
  • 我的 LeetCode 日记:Day 36 - 动态规划,背包问题的千变万化
  • PyTorch神经网络工具箱(神经网络核心组件)