美文网首页
测试几个jvm内存模型的抛出异常

测试几个jvm内存模型的抛出异常

作者: 捉虫大师 | 来源:发表于2018-08-16 23:54 被阅读10次
    栈 StackoverFlowError

    java的栈存放的是一些基本类型的变量,对象引用,它是线程私有的空间,与线程的生命周期相同,也保存方法的局部变量、部分结果,jvm允许java栈的大小是固定的,如果线程在计算中,请求的栈深度大于最大可用栈深度,则抛出StackoverFlowError。复现代码如下:

    package jvm;
    
    public class StackOverflowDemo {
    
        private int count = 0;
    
        private void foo() {
            count++;
            foo();
        }
    
        public static void main(String[] args) {
    
            StackOverflowDemo stackOverflowDemo = new StackOverflowDemo();
    
            for (;;) {
                try {
                    stackOverflowDemo.foo();
                } catch (Throwable e) {
                    System.out.println("count = " + stackOverflowDemo.count);
                    e.printStackTrace();
                    return;
                }
            }
        }
    }
    

    执行输出:

    count = 20454
    java.lang.StackOverflowError
        at jvm.StackOverflowDemo.foo(StackOverflowDemo.java:9)
    

    怎么修改栈可用最大深度呢?可以用-Xss参数修改栈大小来改变最大可达深度,我们设置成

    -Xss1024k
    

    输出结果:

    count = 30105
    java.lang.StackOverflowError
    
    栈 OutofMemoryError

    同样在栈里面会出现OutofMemoryError

    package jvm;
    
    public class OutofMemoryErrorDemo {
    
        public static void main(String[] args) {
    
            for (;;) {
                try {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            while (true) {
                                try {
                                    Thread.sleep(Long.MAX_VALUE);
                                } catch (Exception e) {
                                    
                                }
                            }
                        }
                    }).start();
                } catch (Throwable e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }
    

    这样输出:

    java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
    

    一开始写的时候想的是无限创建线程,但是没有sleep,结果代码运行到去洗了个澡都没有报OutOfMemoryError,洗澡的时候想了一下,可能是因为线程创建太多了导致主线程运行机会变少,这样创建的线程数量是有限的,很难达到OutOfMemoryError,于是加个sleep,让主线程一直创建子线程,果然,很有效果,一下子就出现了。

    堆 OutofMemoryError

    堆存放new出来的对象,所以只要不停的new对象,总会出现OutofMemoryError的。

    package jvm;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class OutofMemoryErrorDemo2 {
    
        public static void main(String[] args) {
            List<Object> list = new ArrayList<Object>();
    
            while (true) {
               list.add(new Object());
            }
        }
    }
    

    输出:

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:3210)
    

    与jvm堆内存相关的参数是
    -Xms128m JVM初始分配的堆内存
    -Xmx512m JVM最大允许分配的堆内存,按需分配

    常量池 OutOfMemoryError

    运行时常量池溢出,在OutOfMemoryError后面跟随的提示信息是“PermGen space”方法去用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。当前很多主流框架,如spring、hibernate,在对类进行增强时,都会使用到GGLib这类字节码技术,增强的类越多,就需要越大的方法区来保证动态生成的Class可以加载入内存。

    这一类异常一时半会也不好测试,而且在jdk 1.8之后也移除了这块。

    相关文章

      网友评论

          本文标题:测试几个jvm内存模型的抛出异常

          本文链接:https://www.haomeiwen.com/subject/nkdabftx.html