简介

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. FaaS 给前端带来了什么?

    一.Serverless 与 FaaS Serverless 是一种云计算理念,即无服务器计算(Serverless Computing): Serverless suggests that the ...

  2. Mybatis核心模块简介

    Configuration 主要字段 Environment:配置DataSource和TransactionFactory ObjectFactory:bean工厂 MapperRegistry:M ...

  3. Everything搜索表达式

    导出搜索列表为txt或csv ​ 索引最近变化 维持一个额外的按照最近变化排序的系统文件数据库,其可以通过 rc: 搜索,或以最近变化排序. ​ 搜索运行次数大于 100: runcount:> ...

  4. Linux企业运维人员最常用命令汇总

    本文目录 线上查询及帮助命令 文件和目录操作命令 查看文件及内容处理命令 文件压缩及解压缩命令 信息显示命令 搜索文件命令 用户管理命令 基础网络操作命令 深入网络操作命令 有关磁盘与文件系统的命令 ...

  5. 解决SyntaxError: Non-UTF-8 code starting with '\xbb'问题

    在第一行加入 # coding=utf-8 2020-06-13

  6. ACwing 147 数据备份 贪心 set

    LINK:数据备份 以前做过这种贪心 不过没有好好的证明 这次来严格的证明一下. 不难发现 最后的答案 选择的所有两对公司必然相邻. 所以排序后 把数组变成ai-ai-1. 这样问他的模型就是 n-1 ...

  7. 4.2 省选模拟赛 流浪者 容斥dp

    求出期望 所有情况很好搞 C(n+m-2,n-1). 也就是说求出所有情况的和乘以上面总方案的逆元即可. 可以发现所有情况和经过多少个障碍点有关 和所处位置无关. 简单的设f[i]表示从1,1到n,m ...

  8. 删除数据-大表根据rowid来删除部分数据

    偶遇需求,大表中需要删除部分数据.分批删除. declare TYPE type_table_rowid IS TABLE OF ROWID INDEX BY BINARY_INTEGER;table ...

  9. static关键字设计原理

    语法只是表象,原理才是关键!!! 灵魂static关键字 Java规定:方法只能由对象来调用. 换句话来说,在面向对象的思维下,方法与对象存在一种强耦合. 方法在没有对象的情况下无法调用,于是上帝派来 ...

  10. 实验01——java模拟银行ATM系统

    用java写的一个模拟银行系统,比较初级. ATM.java package cn.tedu.yinhang; import java.util.Scanner; /** * @author 赵瑞鑫 ...