简介

java.lang.OutOfMemoryError应该java应用程序中非常常见的一个的错误了。

那么OutOfMemoryError产生的原因是什么呢?我们怎么去查找相应的错误呢?一起来看看吧。

OutOfMemoryError

先看一下OutOfMemoryError的定义,OutOfMemoryError继承自

VirtualMachineError,它是Error的一种,表示的是应用程序无法处理的异常,一般情况下会导致虚拟机退出。

public class OutOfMemoryError extends VirtualMachineError {
@java.io.Serial
private static final long serialVersionUID = 8228564086184010517L; /**
* Constructs an {@code OutOfMemoryError} with no detail message.
*/
public OutOfMemoryError() {
super();
} /**
* Constructs an {@code OutOfMemoryError} with the specified
* detail message.
*
* @param s the detail message.
*/
public OutOfMemoryError(String s) {
super(s);
}
}

一般情形下,如果heap没有更多的空间来分配对象,就会抛出OutOfMemoryError。

还有一种情况是没有足够的native memory来加载java class。

在极少数情况下,如果花费大量时间进行垃圾回收并且只释放了很少的内存,也有可能引发java.lang.OutOfMemoryError。

如果发生OutOfMemoryError,同时会输出相应的stack trace信息。

下面我们分析一下各个不同的OutOfMemoryError。

java.lang.OutOfMemoryError: Java heap space

Java heap space表示的是新对象不能在java heap中分配。

如果遇到这种问题,第一个要想到的解决方法就是去看配置的heap大小是不是太小了。

当然,如果是一个一直都在运行的程序,突然间发生这种问题就要警惕了。因为有可能会存在潜在的内存泄露。需要进一步分析。

还有一种情况,如果java对象实现了finalize方法,那么该对象在垃圾回收的时候并不会立刻被回收。而是放到一个finalization队列中。

这个队列会由终结器守护线程来执行。如果终结器守护线程的执行速度比对象放入终结器队列中的速度要慢的话,就会导致java对象不能被及时回收。

如果应用程序创建了高优先级的线程,那么高优先级的线程将有可能会导致对象被放入finalization队列的速度比终结器守护线程的处理速度慢。

java.lang.OutOfMemoryError: GC Overhead limit exceeded

GC overhead limit exceeded表示的是GC一直都在运行,从而导致java程序本身执行非常慢。

如果一个java程序98%的时间都在做GC操作,但是只恢复了2%的heap空间,并且持续5次。那么java.lang.OutOfMemoryError将会被抛出。

可以使用下面的参数来关闭这个功能。

-XX:-UseGCOverheadLimit

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

这个错误的意思是,要分配的array比heap size大。

比如说设置的最大heap大小是256M,但是分配了一个300M的数组,就会出现这个问题。

java.lang.OutOfMemoryError: Metaspace

从JDK8之后,Metaspace已经移到了java的本地内存空间中。如果Metaspace超出了限制的大小,那么java.lang.OutOfMemoryError也会抛出。

Metaspace的空间大小可以通过MaxMetaSpaceSize来设置。

java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?

当本地堆分配失败并且本地堆即将耗尽的时候就会报这个异常。

java.lang.OutOfMemoryError: Compressed class space

在64位的平台,对象指针可以用32位表示(对象指针压缩)。

对象指针压缩可以通过:

UseCompressedClassPointers

来启用,默认这个参数是开启的。

我们可以使用CompressedClassSpaceSize来设置指针压缩空间的大小。

注意,只有klass元信息是存放在CompressedClassSpaceSize设置的空间中的,而其他的元信息都是存放在Metaspace中的。

OutOfMemoryError: reason stack_trace_with_native_method

这个错误表示本地方法遇到分配失败。

遇到这种问题可能需要操作系统的本地调试工具来解决。

总结

本文介绍了OutOfMemoryError的不同种类,希望大家能够有所收获。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jvm-outofmemoryerror-analysis/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

troubleshoot之:分析OutOfMemoryError异常的更多相关文章

  1. OutOfMemoryError异常穷举

    本文内容的目的有两个:第一,通过代码验证Java虚拟机规范中描述的各个运行时区域存储的内容:第二,在工作中遇到实际的内存溢出异常时,能根据异常的信息快速判断是哪个区域的内存溢出,知道什么样的代码可能会 ...

  2. 了解OutOfMemoryError异常 - 深入Java虚拟机读后总结

    JVM中的异常发生 Java虚拟机规范中除了程序计数器外,其他几个运行时区域都有发生OutOfMemoryError异常的可能. 本章笔记通过代码来验证Java虚拟机规范中描述的各个运行时区域存储的内 ...

  3. JVM探秘2--详解内存溢出OutOfMemoryError异常

    JVM运行时内存被划分成多个区域,而除了程序计数器之外,其他几个区都会出现OutOfMemoryError异常,主要原因就是对应内存区域的内存不足以再分配内存,一般要么是内存泄漏了要么就是内存参数设置 ...

  4. OutOfMemoryError异常java内存泄漏(Memory Leak)和内存溢出(Memory Overflow)

    本篇文章理解源自于<深入理解java虚拟机>2.4章节 实战:OutOfMemoryError异常   在以下例子中,所有代码都可以抛出OutOfMemoryError异常,但是要区分到底 ...

  5. JVM --- OutOfMemoryError异常

    在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有可能发生OutOfMemoryError(OOM)异常. 1.Java堆溢出 Java堆用于存储对象实例,只要不断地创 ...

  6. 《深入理解java虚拟机》笔记(3)实战:OutOfMemoryError异常

    一.Java堆溢出 测试代码: /** * <p>Java堆异常测试</p> * <code>VM Args: -Xms20m -Xmx20m -XX:+HeapD ...

  7. 理解 OutOfMemoryError 异常

    OutOfMemoryError 异常应该可以算得上是一个非常棘手的问题.JAVA 的程序员不用像苦逼的 C 语言程序员手动地管理内存,JVM 帮助他们分配内存,释放内存.但是当遇到内存相关的问题,就 ...

  8. 3、实战:OutOfMemoryError异常

    目的:第一,通过代码验证Java虚拟机规范中描述的各个运行时区域存储的内容:第二,工作中遇到实际的内存溢出异常时,能根据异常的信息快速判断是哪个区域的内存溢出,知道什么样的代码可能会导致这些区域内存溢 ...

  9. 剖析Java OutOfMemoryError异常

    剖析Java OutOfMemoryError异常 在JVM中,除了程序计数器外,虚拟机内存中的其他几个运行时区域都有发生OutOfMemoryError异常的可能,本篇就来深入剖析一下各个区域出现O ...

随机推荐

  1. vector基本用法

    Vector作为STL容器中的一员,使用频率非常高,因此对其基本用法和实用技巧进行记录,便于后期查询使用. 基本用法 #include <iostream> #include <ve ...

  2. three.js 数学方法之Plane

    今天郭先生就来继续说一说three.js数学方法中的plane(平面).在三维空间中无限延伸的二维平面,平面方程用单位长度的法向量和常数表示.构造器为Plane( normal : Vector3, ...

  3. 小书MybatisPlus第7篇-代码生成器的原理精讲及使用方法

    本文是本系列文章的第七篇,前6篇访问地址如下: 小书MybatisPlus第1篇-整合SpringBoot快速开始增删改查 小书MybatisPlus第2篇-条件构造器的应用及总结 小书Mybatis ...

  4. 利用Data vault对数据仓库建模

    简介 国内关于Data Vault的信息很少,所以决定写点什么,纯粹都是自己在这个行业10多年的摸爬滚打.不过为了效率,尽量做到简短,直接上干货.对于各个细节大家有不同的理解欢迎来讨论. 数据仓库建模 ...

  5. Shell变量的作用域:Shell全局变量、环境变量和局部变量

    Shell 变量的作用域(Scope),就是 Shell 变量的有效范围(可以使用的范围). 在不同的作用域中,同名的变量不会相互干涉,就好像 A 班有个叫小明的同学,B 班也有个叫小明的同学,虽然他 ...

  6. iframe和DataForm

    一.iframe使用 iframe在一个页面中,相当于整个window窗口的子窗口,可通过页面的元素结构查看. <div> <p>学习iframe</p> < ...

  7. linux gdb 入门级教程(小白专用)

    送给包含我在内的所有小白: 对于养linux真姬的本小白来说,既然你选择养它,那你就要满足他. 如果你养了它是为了码代码,那我觉得gdb应该是它的基本需求了吧?! 然而gdb哪有那些IDE来的简单啊, ...

  8. 4-Pandas之数据类型与数据筛选

    一.数据类型 1.Pandas的数据类型主要结合了pandas和numpy两个模块中的数据类型,包括以下几种: float int bool datetime64[ns]------>日期类型 ...

  9. 1-Numpy的通用函数(ufunc)

    一.numpy“通用函数”(ufunc)包括以下几种: 元素级函数(一元函数):对数组中的每个元素进行运算 数组级函数:统计函数,像聚合函数(例如:求和.求平均) 矩阵运算 随机生成函数 常用一元通用 ...

  10. PHP 命名空间(namespace)定义

    PHP 命名空间(namespace) PHP 命名空间(namespace)是在PHP 5.3中加入的,如果你学过C#和Java,那命名空间就不算什么新事物. 不过在PHP当中还是有着相当重要的意义 ...