场景:有一个单独的服务,用于测试一个大的定时任务(包含大量读写操作),定时任务运行大概 30 分钟后,会出现卡死情况。Java 进程还存在但处于暂停状态。日志停止输出,且没有任何报错。
进程信息: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8831 **** 20 0 9781344 2.491g 14912 t 0.0 8.0 23:50.15 java
gc 部分日志: 2021-11-24T09:43:51.293+0800: 58343.178: [GC (Allocation Failure) [PSYoungGen: 1045888K->416K(1047552K)] 1379025K->333593K(2096128K), 0.0061813 secs] [Times: user=0.02 sys=0.01, real=0.01 secs] 2021-11-24T09:44:37.862+0800: 58389.746: [GC (Allocation Failure) [PSYoungGen: 1046944K->288K(1047552K)] 1380121K->333473K(2096128K), 0.0063377 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 2021-11-24T09:45:23.641+0800: 58435.526: [GC (Allocation Failure) [PSYoungGen: 1046816K->387K(1047552K)] 1380001K->333597K(2096128K), 0.0063043 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
卡死后,jmap,jstack 相关指令都无法再执行了。 数据库用的是 oracle 12c,查看还是正常的,所以应该不是数据库的问题。 请问大佬们,现在有啥排查问题的手段吗?
1
darrh00 2021-11-24 11:22:23 +08:00
什么环境?
如果是 Linux 的话可以试试 kill -QUIT pid |
2
yanweichen0720 2021-11-24 11:25:09 +08:00 1
启动的时候加上远程监控的参数,然后用 jmc 实时看下具体哪些类炸了
|
4
huntagain2008 2021-11-24 11:52:06 +08:00
建议追加附言用 markdown 的代码块把进程信息和日志显示的漂亮点。
|
5
whx 2021-11-24 12:28:46 +08:00 via iPhone
看起来是内存满了不够用导致的,可以把-Xmx 调大一点试下。
|
6
cheng6563 2021-11-24 14:02:45 +08:00 2
-XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=12345.hprof
加这仨参数,使其发生内存问题时直接退出并留下 dump ,然后分析 dump 就行了。 java 发生 OOM 错误时很容易失控,不退出也往往不能正常工作,还不如直接退掉让守护进程重新拉起来了事。 |
7
zxyroy 2021-11-24 15:22:34 +08:00
可以排查下是不是有什么 stream 忘记 close 了
|
8
nonoyang OP @zxyroy 这个应该是不存在的。这个任务只是循环对一些数据进行相关的查询,并做后续的 insert 。只是数据量很大,并且每个数据要做的对应查询也很多。
|
9
nonoyang OP @whx 这个之前已经调高过一次了。现在是-Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m |
11
fengpan567 2021-11-24 16:03:33 +08:00
是不是文件流没关,服务器上 ulimit -n 检查一下打开文件数的限制是多少
|
12
ChovyChu 2021-11-24 16:32:43 +08:00
jstat -gc pid 1000 看一下 gc 频率吧,卡住大概率是经常 fgc 了
|
13
nonoyang OP @ChovyChu 测试了几次,发生了 1 、2 次 full gc ,我不太清楚这个频率是否过高。gc 日志我是有记录的,平均 40s 到 1 分多钟左右执行一次新生代的 gc 。full gc 的记录:
[Full GC (System.gc()) [PSYoungGen: 8519K->0K(958976K)] [ParOldGen: 83126K->75678K(1048576K)] 91646K->75678K(2007552K), [Metaspace: 39477K->39477K(1083392K)], 0.4594062 secs] [Times: user=3.28 sys=0.02, real=0.45 secs] |
14
huang119412 2021-11-24 17:12:23 +08:00
什么都不说,怎么排查,测试机配置和 os 版本,java 版本,框架等。还有系统什么状态?从 Full GC (System.gc())看,这应该回收堆外内存用的。IO 定时任务 CPU 一般占用不会高,最大可能出现在内存和磁盘。我的一个经验是,以前我们测试机用的是机械盘,数据库操作多(随机)的时候,磁盘经常无响应,造成程序假死。
|
15
xylxAdai 2021-11-24 17:33:05 +08:00
strace ?
|
16
zeni123 2021-11-25 01:03:00 +08:00
应该就是内存用多了吧 ParallelGC STW 太长了。增加或者减少堆内存看看从运行时间卡死会不会变化。
这是 java 几,可以换用 G1 吗,换垃圾回收器解决不了卡死问题,但至少会有响应。至于为什么内存会用多了,可以看看有没有内存泄漏。 |
17
nonoyang OP @zeni123 java 8,我换下试试。也是怀疑是内存用多了,但总是直接卡死,没办法获取卡死时的内存使用情况。我准备实在不行,运行一段时间后,不等卡死,提前 dump 。
|
18
Variazioni 2021-11-25 10:17:29 +08:00
我就遇到过类似的问题。。最后用 jProfiler 查到了原因。。
试用期 10 天。。应该够用了吧。 |