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. C++11 Java基本数据类型以及转换

    写在前面: 母语是Java,后来学了C++11,这两个语言的基本数据类型隐式转换不太一样,有点晕,整理一下 整理自网络和书籍,标明出处 C++ 基本数据类型 --http://www.cnblogs. ...

  2. 【ybt高效进阶2-4-3】【luogu P4551】最长异或路径

    最长异或路径 题目链接:ybt高效进阶2-4-3 / luogu P4551 题目大意 给定一棵 n 个点的带权树,结点下标从 1 开始到 N.寻找树中找两个结点,求最长的异或路径. 异或路径指的是指 ...

  3. 在 Spring Boot 2 中致敬 JSP

    新冠病毒

  4. 网站日志统计以及SOA架构

    网站日志统计相关术语 PV(Page View):页面浏览量或点击量,衡量用户访问的网页数量 UV(Unique Visitor):独立设备的访问次数,根据客户端发送的 Cookie 区分 IP(In ...

  5. LINUX - pthread_mutex_lock

    原文链接:https://www.cnblogs.com/fengbohello/p/7571722.html 互斥的概念 在多线程编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性. 每个对 ...

  6. mybatis(三)配置mapper.xml 的基本操作

    参考:https://www.cnblogs.com/wuzhenzhao/p/11101555.html XML 映射文件 本文参考mybatis中文官网进行学习总结:http://www.myba ...

  7. Ubuntu16安装Caffe+Python3缺少libboost

    如果在/usr/lib/x86_64-linux-gnu中找到libboost_python-py3.5.so, 则 sudo ln -s libboost_python-py3.5.so libbo ...

  8. 5分钟学Go 基础01:初识 Go 的第一印象是薪水可观

    本文首发于公众号「5分钟学Go」,一个让你每次花 5 分钟就能掌握一个技能点的公众号.目前在博主连更 5 分钟学Go系列,大家可以关注下,第一时间掌握Go技能.如果想要加群交流,可以在公众号后台回复「 ...

  9. Emacs和Vim:神的编辑器和编辑器之神, 到底哪个更好?

    Emacs和Vim:神的编辑器和编辑器之神, 到底哪个更好? 在这个蔚蓝色的星球上,流传着两大神器的传说:据说Emacs是神的编辑器,而Vim是编辑器之神. 一些人勇敢地拾起了Vim或Emacs,却发 ...

  10. URLSearchParams & shape URL params

    URLSearchParams https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams var paramsString = ...