扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
故障排除
请注意,并非下面所有项目都需要完成。有些问题仅通过遵循几个建议就可以解决。
故障症状
应用程序意外终止。
无法找到与此崩溃相关的核心转储。通常是在启动 JVM 的目录中产生此文件。在 Solaris 上,此文件名称一般为 core,而在 Linux 上,它的名称为 core.
为什么没有核心转储?
当应用程序处理异常时(在 JVM 本身的代码中出现致命问题的情况下发生),通常有可能产生核心转储。但是,如果错误发生在 JNI 或 JDBC 调用中,或者发生在不处理异常的第三方库中,那么当操作系统终止 JVM 时,就不能产生核心转储。
故障排除检查清单
您确信 JVM 真的崩溃了吗?
它可能只要遇到无法处理的问题就会退出。但是,在退出之前,JVM 几乎总会打印和/或记录一条描述性的错误信息。例如,当 JRockit 遇到严重的 JNI 错误时,它会打印消息“ERROR: JNI Panic -- Fatal error: ..”,后面是错误描述,然后它将退出。类似地,当 JRockit 用完本地(即非堆)内存时,它打印消息“Fatal error in JRockit...”,后面是描述性信息,然后退出。JRockit 使用本地内存用于代码生成、生成的代码、优化等。无法获得更多本地内存进行内部操作是一个严重的错误,该错误不易被回滚或忽略。在这些类型的异常情况下,终止 JVM 可能是最好的选择。
检查应用程序日志(或控制台)中的退出时信息是确定 JVM 是否自动终止的快捷方法。
可以产生核心转储吗?
有时候,没有创建核心转储的原因可能非常简单,比如:
用完了磁盘空间或写文件的容量配额
没有在目录中创建或写文件的正确访问权限
以前存在的同名核心转储为只读或写保护状态。
未启用核心转储 [特定于 Unix/Linux]:使用 limit或 ulimit命令确定是否禁用了核心转储,必要时启用它们。例如,在 Linux 上,命令“ulimit -c unlimited”可启用核心转储,而不管其大小如何。如果关心磁盘空间限制问题,则可限制核心转储的大小(有关详细信息,请参阅“man limit”或“man ulimit”。)
如果这些原因都是其影响因素,则纠正此问题以启用要写入的核心转储。然后,如果崩溃可重现,那么最好重现该问题以产生核心转储。
您有转储文件吗?[特定于 JRockit]
如果这是 JRockit 崩溃,则可能已在启动 JRockit 的目录中产生了转储文件(文件名格式为 jrockit.
文件头:包含运行时和系统信息,类似如下:
时间戳
JVM 版本
垃圾回收策略
线程系统(本地线程或瘦线程)
CPU 数目
总物理内存量
操作系统版本
命令行参数(用于 JVM 选项,如堆大小、GC 策略等)
寄存器
堆栈段
代码段
加载的模块(指出崩溃发生在哪个库中)
线程堆栈跟踪:包含发生崩溃的线程的堆栈跟踪
一旦找到相关的转储文件后,线程堆栈跟踪(在该文件的末尾)就提供了非常有用的信息。使用堆栈跟踪中的关键字,可以在下列知识库中搜索以前的团体经验:
AskBEA(BEA 电子支持)
在 BEA 的 JRockit 新闻组上搜索或发贴子
搜索 Google
运气好的时候,可能以前看到过此问题,甚至有可能在 JRockit 修补程序或后期版本中已得到解决。
此崩溃是可重现的吗?
如果问题是一直或经常发生的(或者虽然发生不太频繁,但只要转储是略可重现的),那么我们就比较幸运。在缺少任何核心或转储文件的情况下,剩下的一种方法是尝试缩小导致 JVM 崩溃的问题代码的位置范围。
调试器/IDE
JVM 可以在调试器(gdb、xdb、dbx 等)或 IDE(如 Visual Studio)中启动,以捕捉和处理严重错误。这种方法本身有缺陷,即不能在调试器/IDE 中重现崩溃现象,但如果能重新创建它,则可以从该工具中获得大量有用的信息。
跟踪
可以启用命令行标志 -Xverbose来打开 JVM 中的附加跟踪功能。应用程序也可能有一些可启用的调试标志。
Thread Dump
根据 JVM 版本的不同,有可能在进程退出之前获得 Thread Dump。HotSpot 支持(未记载的)命令行选项 -XX:+ShowMessageBoxOnError;相应的 JRockit 选项为 -Djrockit.waitonerror。当 JVM 崩溃时,它可能会提示用户:“您想要调试此问题吗?” 这会暂停该进程,从而能够生成 Thread Dump(JVM 中的每个线程的一个堆栈跟踪)、连接调试器,或执行一些调试活动。但是,并非在所有情况下这都有效(例如,当堆栈溢出时)。
异地复制
如果能从可重现问题的应用程序提取独立的测试案例,则对快速推进探查过程可能有很大帮助,因为技术支持和工程部门都可以从依赖客户尝试各种建议和修补程序中解放出来。遗憾的是,这几乎总是不可能的,因为客户应用程序一般都会高度依赖于环境,并且与各种第三方应用程序高度关联。
调试编译 [工程特殊情况]
在极端情况下,如果确认很难收集有关该问题的信息,可能会说服 JVM 供应商的工程小组提供调试版编译程序,这会有助于查找问题。但是要注意,这只有在与供应商的支持部门联系之后才能实现。
我们知道什么?
我们掌握的有关崩溃原因的信息越少,我们需要问的问题就越多,以便收集关于环境和应用程序的更多信息。利用经验和知识库搜索,也许能从过去见到的案例中找出该问题。
需要提出的一些关键问题包括:
应用程序的特性是什么?它做些什么?其关键组件是什么?
当应用程序崩溃时,正在做什么?(JNI、JDBC、JSP、JMS、网络通信,等等)
崩溃的性质是什么(它是如何自我表明的)?进程消失,弹出出错对话框,等等。
崩溃发生在应用程序的什么组件中?能把位置缩小到更具体的系统领域吗?例如,如果发生在 JNI 调用中,那么,应用程序代码中做出库调用的的最后位置在哪里?
硬件规范是什么?计算机机型和型号、CPU 数目、物理内存、交换空间,等等。
软件规范是什么?操作系统版本、内核版本、JVM 版本,等等
环境规范是什么?垃圾回收策略、堆大小规格、使用的线程系统、崩溃时的进程大小,等等。
有哪些可用的应用程序/平台日志?
快速修复和解决方法
下列策略可帮助完成探查,也许还能解决问题:
升级
如果可能的话,升级到支持该应用程序的最新 JVM 版本。这不一定能解决问题,但在任何情况下,看看以这种途径能获得哪些免费赠品不失为一个好主意。但是,有些客户也许不能利用此选项,特别是如果应用程序是一个生产系统,必须谨慎控制和严格管理系统修改。
转换 JVM
如果其它供应商的 JVM 支持该应用程序,则转换 JVM 可能有助于避开问题。Sun 的 HotSpot 和 BEA 的 JRockit 在它们的几个关键组件如 JNI、内存管理等的实现上有差异。这些也是经常遇到问题的方面,因此转换 JVM 可能会有所帮助。
禁用 JIT,强迫解释 [特定于 HotSpot]
命令行选项 "-Djava.compiler=none -Xint"强迫 HotSpot 关闭编译和解释所有字节码。如果问题是在“热点”中,这可能有所帮助。
禁用优化 [特定于 JRockit]
命令行选项 "-Xnoopt"强迫 JRockit 关闭所有热点优化(在 JRockit 中无法禁用编译)。由于优化曾是过去出现问题的方面,这可能是一个有用的尝试方法。
转换到 4 类 JDBC 驱动程序
如果崩溃发生在 JDBC 中,那么从 2 类(本地代码)改变到 4 类(纯 Java)JDBC 驱动程序可能会有所帮助。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者