StackOverflowError

在 JVM 的栈中,如果线程要创建的栈帧大小大于栈容量的大小时,就会抛出 java.lang.StackOverflowError。比如下面的代码

public class StackErrorTest {

    public static void main(String[] args) {
main(args);
}
}

无限递归,那么就会不停的创建栈帧,最终撑爆栈空间,抛出栈移除异常。

OOM:Java heap space

堆内存溢出,当堆空间不足以存放创建的对象时就会发生堆异常。具体模拟方式可以参见下面代码:

public class OverHeadOOM {
public static void main(String[] args){
int i = 0;
List<String> list = new ArrayList<>();
try {
while (true){
list.add(String.valueOf(++i));
}
} catch (Exception e) {
System.out.println(i);
e.printStackTrace();
}
} }

为了让结果更快地展示出来,可以把堆空间大小调小一些:-Xms8m -Xmx8m。

OOM:GC overhead limit exceeded

这的发生的原因和上面 Java heap space 差不多,上面是堆空间不足,这个是还未达到堆空间不足,但是超过 98% 的时间用来做 GC 并且回收了不到 2% 的堆内存,这时就会立刻触发当前的异常。

如果以上面的例子来看,如果将堆空间参数设置为 -Xms10m -Xmx10m。就会发生当前异常。

OOM:Direct buffer memory

直接内存溢出。

直接内存是 JVM 向系统申请的内存,由于其是系统内存,所以在 io 时没有状态切换和不必要的数据拷贝,所以相比于非直接内存的 io 执行效率会更高。JDK8 中方法区的实现元空间也是属于直接内存。

在使用 nio 进行缓冲区的定义时,一般是 Buffer.allocate() 来定义的,这种方式是在 JVM 内存中定义空间作为缓冲区的,执行效率也较低;使用 Buffer.allocateDirect() 就是在本地内存中定义的。如果本地内存的可用空间不足以支撑需要分配的空间,就会排除 Direct buffer memory 的异常。具体演示案例可以执行下面代码:

public class DirectBufferOOM {

    public static void main(String[] args){
System.out.println("最大直接内存大小" + (sun.misc.VM.maxDirectMemory()/1024/1024) + "MB");
ByteBuffer.allocateDirect(20*1024*1024);
}
}

执行前需要将直接内存的大小设置为 6m :-XX:MaxDirectMemorySize=6m。

OOM:unable to create new native thread

当前应用程序创建过多的线程,超过设置的限制,就会抛出异常。这个异常一般是在 linux 环境下产生的,windows 下默认是无限制的,linux 下非 root 用户默认为 1024 个,执行下面代码就会抛出此异常。

public class UnableCreateNewThreadDemo {
public static void main(String[] args) {
for(int i = 1; ;i++){
System.out.println("i=" + i);
new Thread(()->{
try { Thread.sleep(Integer.MAX_VALUE); }catch(Exception e) {e.printStackTrace();}
},""+i).start();
}
}
}

如果想要提高上限,除了切换 root 用户外,还可以编辑 /etc/security/limits.d/90-nproc.conf ,增加当前用户的名字,为其设置可以创建的线程数

OOM:Metaspace

元空间空间不足。因为在 JDK8 开始方法区实现变成了元空间,所以当创建了过多的类时,就会抛出这个异常。

触发案例:

public class MetaspaceOOM {
static class OOMTest{}
public static void main(String[] args){
int i = 0;
try {
while (true){
i++;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMTest.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o, args);
}
});
enhancer.create();
}
} catch (Throwable throwable) {
System.out.println("执行了" + i + "次");
throwable.printStackTrace();
}
}
}

Enhancer 是 Spring cglib中用于生成动态代理的类,可以为未实现接口的类创建代理。在上面代码中就是通过 Enhancer 不停地创建代理对象(创建代理对象的同时也会将代理类加载到方法区中)来模拟元空间不足的场景。为了现象更明显,可以将元空间大小设置得小一些:-XX:MetaspaceSize=15m -XX:MaxMetaspaceSize=15m。

JVM 中的异常的更多相关文章

  1. Java中的异常-Throwable-Error-Exception-RuntimeExcetpion-throw-throws-try catch

    今天在做一个将String转换为Integer的功能时,发现Integer.parseInte()会抛出异常NumberFormatException. 函数Integer.parseInt(Stri ...

  2. jruby中的异常

    先看看ruby中的异常知识: 异常处理raise 例子: raise raise "you lose" raise SyntaxError.new("invalid sy ...

  3. JAVA中的异常(异常处理流程、异常处理的缺陷)

    异常处理流程 1)首先由try{...}catch(Exception e){ System.out.println(e); e.printStackTrace(); }finally{...}结构 ...

  4. 《深入Java虚拟机学习笔记》- 第7章 类型的生命周期/对象在JVM中的生命周期

    一.类型生命周期的开始 如图所示 初始化时机 所有Java虚拟机实现必须在每个类或接口首次主动使用时初始化: 以下几种情形符合主动使用的要求: 当创建某个类的新实例时(或者通过在字节码中执行new指令 ...

  5. JVM中class文件探索与解析(一)

    一直想成为一名优秀的架构师的我,转眼已经工作快两年了,对于java内核了解甚少,闲来时间,看看JVM,吧自己的一些研究写下来供大家参考,有不对的地方请指正. 废话不多说,一起来看看JVM中类文件是如何 ...

  6. Java中的异常和处理详解

    简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. ...

  7. 【JVM虚拟机】(9)-- JVM是如何处理异常的

    [JVM虚拟机](9)-- JVM是如何处理异常的 上篇博客我们简单说过异常信息是存放在属性表集合中的Code属性表里,那么这篇博客就单独讲Code属性表中的exception_table. 在讲之前 ...

  8. 第33节:Java面向对象中的异常

    Java中的异常和错误 Java中的异常机制,更好地提升程序的健壮性 throwable为顶级,Error和Exception Error:虚拟机错误,内存溢出,线程死锁 Exception:Runt ...

  9. JVM中对象的回收过程

      当我们的程序开启运行之后就,就会在我们的java堆中不断的产生新的对象,而这是需要占用我们的存储空间的,因为创建一个新的对象需要分配对应的内存空间,显然我的内存空间是固定有限的,所以我们需要对没有 ...

随机推荐

  1. PowerShell随笔1---背景

    既然是随笔,那就想到什么说什么,既会分享主题知识,也会分享一些其他技巧和个人学习方法,供交流. 我一般学习一个东西,我都会问几个问题: 这东西是什么? 这东西有什么用,为什么会出现,出现是为了解决什么 ...

  2. MHA 高可用介绍

    目录 MHA 介绍 MHA 简介(Master High Availability) MHA 工作原理(转载) MHA 架构 MHA 工具 Manager 节点 Node 节点 MHA 优点 MHA ...

  3. Gitlab 快速部署及日常维护 (一)

    一.GitLab简介GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务 二.GitLab系统架构git用户的主目录通常是/home/git(~ ...

  4. spring-cloud-netflix-hystrix-dashboard

    Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数 ...

  5. Github access token

    Github access token https://github.com/settings/tokens https://docs.github.com/en/free-pro-team@late ...

  6. AIoT & IoT

    AIoT & IoT Artificial Intelligence of Things Internet of Things AIoT === AI + IoT 人工智能物联网 === 人工 ...

  7. ES2021 & Pipeline operator (|>) / 管道运算符 |>

    ES2021 & Pipeline operator (|>) / 管道运算符 |> demo "use strict"; /** * * @author xg ...

  8. Vue & mobile UI components

    Vue & mobile UI components https://github.com/vuejs/awesome-vue https://awesome-vue.js.org/ http ...

  9. 彻底理解c++的隐式类型转换

    隐式类型转换可以说是我们的老朋友了,在代码里我们或多或少都会依赖c++的隐式类型转换. 然而不幸的是隐式类型转换也是c++的一大坑点,稍不注意很容易写出各种奇妙的bug. 因此我想借着本文来梳理一遍c ...

  10. css优先级和权重

    1. 权重概念: 权重,是一个相对的概念,是针对某一指标而言.某一指标的权重是指该指标在整体评价中的相对重要程度. 权重系数,是表示某一指标项在指标项系统中的重要程度,它表示在其它指标项不变的情况下, ...