JVM挂掉后产生hs_err_pid文件,有什么方法确定是什么原因导致的吗

时间:2023-01-22 11:50:19
最近实验室测试应用,连续两次jvm挂掉只产生了hs_err_pid文件,通过hs_err_pid文件分析业务实在困难,有什么办法知道jvm为什么突然挂掉吗?

1、两次jvm挂掉一次是跑了3天后的凌晨,一次是在跑了一天后的下午且两次打印的问题堆栈都不一样,因此怀疑跟业务代码有关
2、两次挂掉时候产生的hs_err_pid文件中的内存使用情况都属于正常,所以定位问题的方向很模糊

下面是两次hs_err_pid文件中显示的jvm崩溃的堆栈
Stack: [0x00007f8892995000,0x00007f8892a96000],  sp=0x00007f8892a940e0,  free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x62b071]  HeapRegionDCTOC::walk_mem_region(MemRegion, HeapWord*, HeapWord*)+0x91
V  [libjvm.so+0x9eae33]  DirtyCardToOopClosure::do_MemRegion(MemRegion)+0x113
V  [libjvm.so+0x5cb578]  ScanRSClosure::doHeapRegion(HeapRegion*)+0x318
V  [libjvm.so+0x59b610]  G1CollectedHeap::collection_set_iterate_from(HeapRegion*, HeapRegionClosure*)+0x30
V  [libjvm.so+0x5caade]  G1RemSet::scanRS(G1ParPushHeapRSClosure*, CodeBlobClosure*, unsigned int)+0xce
V  [libjvm.so+0x5cae24]  G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure*, CodeBlobClosure*, unsigned int)+0xe4
V  [libjvm.so+0x5ce221]  G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure*, OopClosure*, unsigned int)+0xa1
V  [libjvm.so+0x5ae1e2]  G1ParTask::work(unsigned int)+0x3f2
V  [libjvm.so+0xaed0ff]  GangWorker::loop()+0xcf
V  [libjvm.so+0x92a728]  java_start(Thread*)+0x108


第二次的
Stack: [0x00007efe2b183000,0x00007efe2b284000],  sp=0x00007efe2b282050,  free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x9f1690]  SparsePRT::add_card(int, int)+0x40
V  [libjvm.so+0x63127a]  OtherRegionsTable::add_reference(void*, int)+0x12a
V  [libjvm.so+0x64ea04]  InstanceKlass::oop_oop_iterate_nv(oopDesc*, FilterOutOfRegionClosure*)+0xb4
V  [libjvm.so+0x62a2a6]  HeapRegion::oops_on_card_seq_iterate_careful(MemRegion, FilterOutOfRegionClosure*, bool, signed char*)+0x2e6
V  [libjvm.so+0x5c9f5c]  G1RemSet::refine_card(signed char*, unsigned int, bool)+0x20c
V  [libjvm.so+0x5cb045]  RefineRecordRefsIntoCSCardTableEntryClosure::do_card_ptr(signed char*, unsigned int)+0x25
V  [libjvm.so+0x565f5e]  DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure*, unsigned int, int, bool)+0xce
V  [libjvm.so+0x59d502]  G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure*, DirtyCardQueue*, bool, unsigned int)+0x62
V  [libjvm.so+0x5cae07]  G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure*, CodeBlobClosure*, unsigned int)+0xc7
V  [libjvm.so+0x5ce221]  G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure*, OopClosure*, unsigned int)+0xa1
V  [libjvm.so+0x5ae1e2]  G1ParTask::work(unsigned int)+0x3f2
V  [libjvm.so+0xaed0ff]  GangWorker::loop()+0xcf
V  [libjvm.so+0x92a728]  java_start(Thread*)+0x108


两次挂掉时jvm参数都加了HeapDumpOnOutOfMemoryError,所用版本1.8.0_151
疑问:
1、这种情况jvm为啥不产生heapdump文件
2、对于jvm只产生hs_err_pid文件的还有什么定位手段

11 个解决方案

#1


不会,嘿嘿 JVM挂掉后产生hs_err_pid文件,有什么方法确定是什么原因导致的吗

#2


你好,你的那两个问题我无法回答,但是可以帮你分析下JVM挂掉的原因,通常来说,JVM挂掉,都是下面三个问题之一

1.GC的安全性检查失败:一旦GC花费的时间占到98%以上的话,JVM就会宣告投降了: java.lang.OutOfMemoryError: GC overhead limit exceeded。

2.无法为下一个操作分配足够的内存:如果无法满足下一条指令所需要分配的内存的话,你会收到一条”java.lang.OutOfMemoryError: Java heap space” 的错误信息。

3.还有一种情况是你的内存已经紧张到连JVM创建一条OutOfMemoryError异常,填充堆栈信息,打印到屏幕上这点要求都满足不了了。这种情况UncaughtExceptionHandler会捕获到这个错误,而不再走通常的错误流程。这个处理器恰如其名,当线程由于某个异常快要挂掉的时候,它开始出来收场了。出现这种情况的话,JVM会找到线程对应的 UncaughtExceptionHandler,然后调用它的uncaughtException方法。

#3


还有一个办法可以帮你快速定位到是哪里的问题,那就是用try-catch,把代码放在try-catch中,如果哪崩溃了,会有提示

#4


再给你提供个解决思路,写一个定时启动脚本,做个守护,发现进程不存在了,马上拉起来。

#5


引用 4 楼 mj280824108 的回复:
再给你提供个解决思路,写一个定时启动脚本,做个守护,发现进程不存在了,马上拉起来。

这个方法我已经实施了,但是只是暂时解决,我是很想搞明白这个原因

#6


https://www.cnblogs.com/jjzd/p/6519686.html    看的网上有这篇描述,但是他的已经确定是jdk修复的bug了,从他这个分析的,我少贴来了关键信息出来了

#7


OutOfMemoryError一般是程序占用了大量的内存。首先看你的程序是做什么的,其中有什么逻辑会产生大量的(猜测70%的可能是这个对象)StringBuffer/StringBuilder之类的对象。

#8


可以自己生成heapdump文件来分析,借助jvm的一些工具比如jmap/jstack/jstat来分析

#9


Memory Analyzer Tool 用这个可以定位到具体那个地方出问题了,前提是hs_err_pid文件别太大。

#10


1、大部分是物理内存不足造成。

2、jdk自带的jconsole、jvis...等可以监控。

#11


前段时间遇到了类似的问题,后来确定是jvm bug。
你可以换个jvm 版本看看

#1


不会,嘿嘿 JVM挂掉后产生hs_err_pid文件,有什么方法确定是什么原因导致的吗

#2


你好,你的那两个问题我无法回答,但是可以帮你分析下JVM挂掉的原因,通常来说,JVM挂掉,都是下面三个问题之一

1.GC的安全性检查失败:一旦GC花费的时间占到98%以上的话,JVM就会宣告投降了: java.lang.OutOfMemoryError: GC overhead limit exceeded。

2.无法为下一个操作分配足够的内存:如果无法满足下一条指令所需要分配的内存的话,你会收到一条”java.lang.OutOfMemoryError: Java heap space” 的错误信息。

3.还有一种情况是你的内存已经紧张到连JVM创建一条OutOfMemoryError异常,填充堆栈信息,打印到屏幕上这点要求都满足不了了。这种情况UncaughtExceptionHandler会捕获到这个错误,而不再走通常的错误流程。这个处理器恰如其名,当线程由于某个异常快要挂掉的时候,它开始出来收场了。出现这种情况的话,JVM会找到线程对应的 UncaughtExceptionHandler,然后调用它的uncaughtException方法。

#3


还有一个办法可以帮你快速定位到是哪里的问题,那就是用try-catch,把代码放在try-catch中,如果哪崩溃了,会有提示

#4


再给你提供个解决思路,写一个定时启动脚本,做个守护,发现进程不存在了,马上拉起来。

#5


引用 4 楼 mj280824108 的回复:
再给你提供个解决思路,写一个定时启动脚本,做个守护,发现进程不存在了,马上拉起来。

这个方法我已经实施了,但是只是暂时解决,我是很想搞明白这个原因

#6


https://www.cnblogs.com/jjzd/p/6519686.html    看的网上有这篇描述,但是他的已经确定是jdk修复的bug了,从他这个分析的,我少贴来了关键信息出来了

#7


OutOfMemoryError一般是程序占用了大量的内存。首先看你的程序是做什么的,其中有什么逻辑会产生大量的(猜测70%的可能是这个对象)StringBuffer/StringBuilder之类的对象。

#8


可以自己生成heapdump文件来分析,借助jvm的一些工具比如jmap/jstack/jstat来分析

#9


Memory Analyzer Tool 用这个可以定位到具体那个地方出问题了,前提是hs_err_pid文件别太大。

#10


1、大部分是物理内存不足造成。

2、jdk自带的jconsole、jvis...等可以监控。

#11


前段时间遇到了类似的问题,后来确定是jvm bug。
你可以换个jvm 版本看看