java Unknown error_如何修复Java中的VirtualMachineError

原标题:如何修复Java中的VirtualMachineError

来自:唐尤华

译自:https://jaxenter.com/java-virtual-machine-error-154691.html

即使是最好的代码也会抛出错误,对开发人员而言这意味着需要知道如何修复它们。在这篇文章中,Ram Lakshmanan 介绍了许多不同类型的 VirtualMachineError 以及如何解决这些问题,在应用程序不崩溃的前提下回到正常状态。

当 Java 虚拟机遇到内部错误或资源限制无法运行时,就会抛出 Java.lang.VirtualMachineError。它是 JVM 的一种自我防御机制,用于防止整个应用程序崩溃。 在本文中,我将讨论许多不同类型的 VirtualMachineError,它们各自的特点、各种触发原因、以及几种可能的修复方案。

1. VirtualMachineError 的类型

有四种不同类型的 VirtualMachineError:

OutOfMemoryError

StackOverflowError

InternalError

UnknownError

让我们在本节中详细回顾这些类型。

5a2f0d5b5f18bd94ce982a1bb0160aeb.png

Java throwable 类层次结构

1.1 OutOfMemoryError

就像 OMG(Oh My God)的首字母缩写一样,OOM(OutOfMemoryError)在 DevOps 社区中非常流行。 虽然大多数 DevOps 的工程师可能认为只有一种 OutOfMemoryError,但实际上 OutOfMemoryError 有八种不同类型:

java.lang.OutOfMemoryError:Java 堆空间

java.lang.OutOfMemoryError:GC 开销超过限制

java.lang.OutOfMemoryError:请求的数组大小超过虚拟机限制

java.lang.OutOfMemoryError:Permgen 空间

java.lang.OutOfMemoryError:Metaspace

java.lang.OutOfMemoryError:无法新建本机线程

java.lang.OutOfMemoryError:杀死进程或子进

java.lang.OutOfMemoryError:发生 stack_trace_with_native_method

触发每种错误的原因各有不同。类似地,根据 OutOfMemoryError 不同的问题类型,对应的解决方案也不一样。这里有一份很好的文档,用一页纸总结了所有不同类型的 OutOfMemoryError、触发原因和解决方案。

通常可以通过分析垃圾回收日志和堆转储文件来诊断和修复 OutOfMemoryError 错误。手动分析垃圾回收日志可能会很乏味,可以考虑使用免费工具,如 GCeasy、HP Jmeter 或 IBM GC analyzer。 类似地,也可以考虑使用 HeapHero 或 Eclipse MAT 这样的免费工具来分析堆转储文件。

参见:StackOverFlowError:原因及解决方案

1.2 StackOverflowError

线程的堆栈存储了执行的方法、基本数据类型值、局部变量、对象指针和返回值信息,所有这些都会消耗内存。如果线程的堆栈大小超过了内存分配限制,那么就会抛出 java.lang.StackOverflowError。通常由于执行程序中有一个错误,在线程重复递归调用同一个函数时会发生这个问题。关于如何调试 StackOverflowError 的细节以及修复这个问题可能的解决方案,更多信息可以看这里。

1.3 InternalError

JVM 抛出 java.lang.InternalError 有三个原因,虚拟机软件出现错误、系统软件底层出现错误或者硬件出现故障。

然而,很少会遇到 InternalError 这样的错误。要了解哪些特定情况可能导致 InternalError,请在 Oracle 的 Java Bug 数据库 中搜索 InternalError。在写这篇文章的时候(2018年12月20日),Oracle Java Bug 数据库中仅报告了200个 InternalError,而且大多数都已经修复了,所以不必对此过于担心。

1.4 UnknownError

当发生异常或错误,但 Java 虚拟机无法报告确切的异常或错误时,就会抛出 java.lang.UnknownError。UnknownError 很少出现。事实上,在 Oracle Java Bug 数据库中搜索 UnknownError 时,只找到了2个 Bug。

参见:远程调试 Java 应用程序2. 特征

VirtualMachineError 有两个主要特征:

非受检异常(Unchecked exceptions)

同步模式与异步模式

让我们在本节中讨论这两个特征。

2.1 非受检异常

有两种异常类型:受检异常和非受检异常。

在编译时检查的异常称为受检异常。如果代码中的某些方法抛出受检异常,那么该方法必须处理该异常或者使用 throws 关键字指定异常。受检异常包括 IOException、SQLException、DataAccessException、ClassNotFoundException 等。

非受检异常常没有这个要求,它们不需要捕获或者声明抛出。所有类型的 VirtualMachineError 都是非受检异常。

2.2 同步模式与异步模式

可以在两种模式下抛出异常:同步模式和异步模式。

同步异常在特定程序语句执行时发生,无论该程序在类似的环境中执行了多少次。同步异常的例子有 NullPointerException、 ArrayIndexOutOfBoundException 等。

异步异常可以在任何时间点和程序语句的任何部分发生,异常抛出的地方也不一样。所有的 VirtualMachineError 都是异步抛出的,但有时也会同步抛出。StackOverflowError 可能随方法调用而同步抛出,也可能随着本地方法执行或 Java 虚拟机资源限制异步抛出。类似地,OutOfMemoryError 可能在对象创建、数组创建、类初始化和装箱转换时同步或异步抛出。StackOverFlowError 原因及解决方案:https://jaxenter.com/stackoverflowerror-causes-152027.html

远程调试 Java 应用程序: https://jaxenter.com/remote-debugging-java-applications-151466.html

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值