JVM hang时,Eden区100%,所有线程包括gc线程被 blocked分析

来源:互联网 发布:电脑语音读书软件 编辑:程序博客网 时间:2024/06/08 05:33
jstat -gcutil pid 1000
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  5.68  36.18 100.00   1.50  11.93     14    0.555     0    0.000    0.555
  5.68  36.18 100.00   1.50  11.93     14    0.555     0    0.000    0.555
  5.68  36.18 100.00   1.50  11.93     14    0.555     0    0.000    0.555
  5.68  36.18 100.00   1.50  11.93     14    0.555     0    0.000    0.555

jstack -F pid 
Attaching to process ID 16063, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.0-b56
Deadlock Detection:

No deadlocks found.

Thread xxx: (state = BLOCKED)

Thread xxx: (state = BLOCKED)

..........

Thread xxx: (state = BLOCKED)


Eden区100%时,应用申请内存不能分配,触发ygc,vmThread执行ygc,分配给GCTaskThread执行,vmThread需要等GCTaskThread执行完成后才返回。但是GCTaskThread在执行过程中有时需要分配堆内存。而这时Heap lock已经被申请内存分配的应用线程持有,这样变成死锁。

应用线程为什么要获取heap_lock呢?因为如果一个线程因为内存不能分配而触发gc的话,那么其它线程再申请同样会如此,所以第一次触发gc的线程持有这个锁可以让其它应用线程等待而不要再产生同样的操作,否则vmThread执行队列中会有同样的原因的大量操作。

CTaskThread在执行过程中有时需要分配堆内存的原因是可能产生异常(校验,load),而异常信息必须申请堆内存(java空间)才能返回给应用方。


目前我们无法指定vm预留这些堆用来处理这种特发情况 ,算是一个坑吧。


0 0
原创粉丝点击