如何在Java中修复VirtualMachineError

当Java虚拟机遇到任何内部错误或资源限制而导致其无法运行时,将引发Java.lang.VirtualMachineError 这是JVM用来防止整个应用程序崩溃的一种自防御机制。 在本文中,我将讨论VirtualMachineError的许多不同类型,它们的特性,触发它们的各种原因,以及修复它们的几种可能的解决方案。

VirtualMachineError的类型

有四种不同类型的VirtualMachineError:

  1. OutOfMemoryError
  2. *Error
  3. 内部错误
  4. 未知错误

让我们在本节中详细检查这些类型。

如何在Java中修复VirtualMachineError

图:Java throwable类层次结构

OutOfMemoryError

就像OMG(Oh My God)的缩写一样,OOM(OutOfMemoryError)在DevOps社区中也很流行。 尽管大多数DevOps工程师可能认为只有一个OutOfMemoryError,但实际上有八种不同的OutOfMemoryError:

  • java.lang.OutOfMemoryError:Java堆空间
  • java.lang.OutOfMemoryError:超出了GC开销限制
  • java.lang.OutOfMemoryError:请求的数组大小超出了VM限制
  • java.lang.OutOfMemoryError:Permgen空间
  • java.lang.OutOfMemoryError:元空间
  • java.lang.OutOfMemoryError:无法创建新的本机线程
  • java.lang.OutOfMemoryError:杀死进程或牺牲子进程
  • java.lang.OutOfMemoryError:原因stack_trace_with_native_method

每个错误都是由不同的原因触发的。 同样,针对这些错误的解决方案因OutOfMemoryError问题的类型而异。 这是一份漂亮的一页文档 ,总结了所有不同类型的OutOfMemoryError及其原因和解决方案。

通常,可以通过分析垃圾回收日志和堆转储来诊断和修复OutOfMemoryError。 由于手动分析垃圾收集日志可能很繁琐,因此您可以考虑使用免费工具,例如GCeasyHP JmeterIBM GC分析仪 同样,您可以考虑使用免费的工具(如HeapHeroEclipse MAT)来分析堆转储。

还请参见: *Error:原因和解决方案

*Error

线程的堆栈堆栈存储有关其执行的方法,原始数据类型值,局部变量,对象指针和返回值的信息。 所有这些东西消耗内存。 如果线程的堆栈大小增加到超出分配的内存限制,则将抛出java.lang.*Error。 当线程由于执行程序中的错误而一次又一次地递归调用同一函数时,通常会发生此问题。 有关如何调试*Error和所有可能的解决方案的更多详细信息,请参见此处

内部错误

JVM抛出java.lang.InternalError的原因有三个。 如果实现虚拟机的软件出现故障,底层主机系统软件出现故障,或者硬件出现故障。

但是,很少遇到这种InternalError。 要了解哪些特定情况可能导致InternalError,请在Oracle的Java Bug数据库中搜索“ InternalError”字符串。 在撰写本文时(2018年12月20日),Oracle的Java Bug数据库中仅针对此错误报告了200个缺陷。 他们大多数是固定的。 因此,不必对此太担心!

未知错误

当发生异常或错误但Java虚拟机无法报告实际的异常或错误时,将引发java.lang.UnknownError。 很少发生UnknownError。 实际上,在Oracle Java Bug数据库中搜索“ UnknownError”时,仅发现2个缺陷

还请参见: Java应用程序的远程调试

特点

VirtualMachineError具有几个主要特征:

  • 未经检查的异常
  • 同步和异步交付

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

未经检查的异常

有两种类型的异常:选中和未选中。

在编译时检查的异常称为检查异常。 如果代码中的某些方法引发了检查的异常,则该方法必须处理该异常,或者必须使用'throws'关键字指定该异常。 已检查异常的示例包括:IOException,SQLException,DataAccessException,ClassNotFoundException等。

未检查的异常没有此要求。 它们不必被捕获或声明为抛出。 所有类型的VirtualMachineError都是未经检查的异常。

同步和异步交付

可以以两种方式引发异常:同步和异步。

同步异常发生在特定的程序语句上,而不管程序在类似环境中执行了多少次。 同步异常的示例包括NullPointerException,ArrayIndexOutOfBoundException等。

异步异常可以在程序语句的任何时间和任何部分发生。 没有一致性可以将其抛出。 所有VirtualMachineErrors都是异步引发的,但有时也可以同步引发。 由于本机方法执行或Java虚拟机资源限制,方法调用可能会引发*Error同步,也可能引发异步。 同样,在对象创建,数组创建,类初始化和装箱转换过程中,可能会异步引发OutOfMemoryError,也可能异步引发。

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