当前位置: 首页 > 面试题库 >

Java VM:在1.6.0_17和1.6.0_18上均可重现的SIGSEGV,如何报告?

阎嘉荣
2023-03-14
问题内容

编辑 :此可重现的SIGSEGV发生在具有多个proc和2GB以上的mem的Linux机器上,因此Java默认为-
server模式。有趣的是,如果我强制使用“ -client”,就不会再崩溃了……(我仍然不太确定如何处理可复制的SIGSEGV,但这仍然很有趣)。

首先请注意,这有点相关,但与以下内容并不相同,因为在我们的案例中,这只是发生了SIGSEGV,我们可以可靠地触发它:

之所以相关,是因为当我们向我们的应用程序提供“大量数据”时会发生这种情况:数据来自文本文件,然后进行数字处理(是的,Java中的财务数字处理)。

我可以仅使用有效的Java代码可靠地将JVM触发到SIGSEGV。

注意 :我总是会导致JVM 1.6.0_17和JVM 1.6.0_18都崩溃,这个问题不是关于如何解决此问题的(例如,使用VM参数 可以
解决此问题,但我想知道的不是)该可重复生成的SIGSEGV怎么办)。

我有一个解决方法,它只是在启动我们的应用程序时使用Java 1.5(同时仍使用Java 1.6在同一台计算机上同时运行IntelliJ
IDEA等),但是我的问题是是否应该报告此问题,并且,如果应该的话,知道日志本身包含专有信息(完整的hs_err log),如何进行报告。

可以排除以下硬件错误:

  • 这是在定期达到正常运行时间的工作站上发生的(我仅在发布影响到经过精简和加固的Debian Linux的关键安全补丁时才重新启动它,这种情况实际上很少发生),并且应用程序从不崩溃(使其非常崩溃)不太可能是那台机器上的硬件问题[更多内容])

  • 相同的应用程序可以在相同的负载下在JVM 1.5上的同一台机器上完美运行(这就是我测试该应用程序的方式:我只是在1.5 VM下启动它)

  • 在相同(巨大)负载下,同一应用程序可以在一百多台客户端计算机上正常运行(在Windows + JVM 1.5或1.6上绝不会崩溃,而在OS X + JVM 1.5或1.6上绝不会崩溃[崩溃意味着即时电话客户致电])

  • 同一台机器上的其他应用程序以及相同的1.6.0_17或1.6.0_18 JVM永远不会崩溃(例如,我有IntelliJ IDEA的两个实例在同一台机器上以两个不同的用户身份运行,并且它们没有崩溃)

  • 在memtest上“定期”对机器进行了测试(在安装新操作系统之前,不久前我安装Debian Lenny时就发生了)

这是按需重现的SIGSEGV:

... $uname -a
Linux saturn 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 UTC 2009 i686 GNU/Linux
... $ export /home/wizard/jdk1.6.0_17/bin:$PATH
... $ java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Server VM (build 14.3-b01, mixed mode)

启动应用程序,向其发送“大量数据”,等待几秒钟…

然后,对于1.6.0_17总是:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xb76d0080, pid=30793, tid=2514328464
#
# JRE version: 6.0_17-b04
# Java VM: Java HotSpot(TM) Server VM (14.3-b01 mixed mode linux-x86 )
# Problematic frame:
# V  [libjvm.so+0x4bc080]
#
# An error report file with more information is saved as:
# /home/wizard/hs_err_pid30793.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp

(请注意,在每个SIGSEGV中,“ [libjvm.so + 0x4bc080]”行对于1.6.0_17都是一致的)

或1.6.0_18:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xb77468f0, pid=722, tid=2514516880
#
# JRE version: 6.0_18-b07
# Java VM: Java HotSpot(TM) Server VM (16.0-b13 mixed mode linux-x86 )
# Problematic frame:
# V  [libjvm.so+0x4d88f0]
#
# An error report file with more information is saved as:
# /home/wizard/hs_err_pid722.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
Aborted

(请注意,在每个SIGSEGV处,“ [libjvm.so + 0x4d88f0]”行与1.6.0_18一致)

问题在于日志文件包含无法共享的专有信息。

复制“微小的测试用例”来复制问题也不现实:这类似于上面链接的问题,只有在将“大量数据”馈送到应用程序时才会发生。

请注意,在完全相同的硬件,完全相同的JVM,但另一个Linux版本(我之前有Debian Etch)的完全相同的应用程序不会一次触发该SIGSEGV。

但这并不意味着JVM不会出错:它仍然可能是JVM问题。

我应该报告此事以及如何报告?(请记住,编写“可重现的小型测试用例”是一种幻想,并且日志中包含不应泄露的专有信息)。我应该只编辑日志并发送它吗?

当您的日志中包含专有信息并且测试案例无法再现问题时,报告这种可重现的SIGSEGV的程序如何?

你们中有没有人成功打开了这样的错误,然后在后续的Java版本中看到了解决的问题?

您认为报告这样的问题对“ Java社区”来说是好事,还是我不应该因为它不重要而打扰?


问题答案:

我升级到JDK 1.6_18时遇到类似的问题,似乎可以使用以下选项解决:

-server
-Xms256m
-Xmx748m
-XX:MaxPermSize=128m

-verbose:gc
-XX:+PrintGCTimeStamps
-Xloggc:/tmp/gc.log
-XX:+PrintHeapAtGC
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath="/tmp"

-XX:+UseParallelGC
-XX:-UseGCOverheadLimit

# Following options just to remote monitoring with jconsole, useful to see JVM behaviour at runtime
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=MyHost

我仍然没有仔细检查(这是生产环境),但是我认为错误是由于两个原因造成的:

1)关于堆和/或永久空间的错误设置(我认为JDK 1.6在堆和永久空间中需要比以前的JVM版本更多的空间)导致OutOfMemoryError,但是

2)在错误的原始设置中有人写了

-XX:+HeapDumpOnOutOfMemoryError="/tmp"

并不是

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath="/tmp"

因此,JVM可能无法编写heapdump,而我们仅得到了SIGSEGV(以前的版本在工作目录中写入了heap dump)。

也检查-server -XX:+UseParallelGC-XX:-UseGCOverheadLimit选项。我认为使用VM参数不是一种解决方法,而是正确的方法,因为垃圾收集器(不仅是)在1.5到1.6之间变化。



 类似资料:
  • 问题内容: 我只想在星期一至星期五报警。我的代码在这里 有个主意。 问题答案: 请尝试此代码。已在我的应用中成功运行

  • 问题内容: 我知道关于均衡器有很多问题,但是我没有得到我一直在寻找的东西。我想要做的是一个均衡器,用于以如下方式修改音频样本: 我不确定这是否是我想要的确切接口,因为我对DSP的实现知之甚少(我使用了滤波器,限幅器,压缩器,但没有制造出来)。 因此,在Google搜索上我读到我必须对采样进行FFT,以便获取每个频率范围的数据而不是幅度,按照我想要的方式进行处理,然后对FFT求逆,以便再次在音频采样

  • 我在一个事务控制器下运行了一个Jmeter脚本,其中包含所有示例,如下图所示 然后,当我得到这个测试的总结报告,并在reportunderaverage列中发现事务控制器显示了所有样本的平均时间的总和。问题1:为什么事务控制器也显示为示例?问题2:(勾选下面的摘要报告图像)总平均值不应该是7608/17(其中事务控制器平均值为7608,样本数为17)如果您看到下面的摘要报告,您可以看到显示的平均时

  • 我在beanstalk和配置的nginx实例上有一个经典的负载均衡器。我想重定向http到https请求。 我设置了负载均衡器侦听器重定向到端口80到它的实例。 我在.ebextensions/nginx_config.config中创建了一个文件,在其中设置重定向并筛选出HealthCheck。 请参阅下面的配置重写: 但似乎什么也没有发生,服务器仍然没有重定向到HTTPS。好像我的配置被忽略了

  • (1)什么是可重入性 一个线程持有锁时,当其他线程尝试获取该锁时,会被阻塞;而这个线程尝试获取自己持有锁时,如果成功说明该锁是可重入的,反之则不可重入。 (2)synchronized是如何实现可重入性 synchronized关键字经过编译后,会在同步块的前后分别形成monitorenter和monitorexit两个字节码指令。每个锁对象内部维护一个计数器,该计数器初始值为0,表示任何线程都可

  • 我有一组从共享类型继承的域对象(即、)。子类型具有特定的属性(即、)。 此外,作为解析日志文件的结果,我有一个包含混合子类型的记录列表。 为了计算日志记录上的统计信息,我想只在匹配特定子类型的记录子集上应用数学函数,即只在s上应用数学函数。因此,我希望有一个特定子类型的过滤流。我知道可以使用以下方法将和应用到子类型 在流上多次应用这个filter&cast(特别是在对同一子类型进行多次不同计算时)