JVM自动内存管理机制 二

java堆用于存储对象实例,只要不断创建对象,并且保证GC Roots(一直GC回收算法)到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么对象在对象数量到达最大堆的容量限制后就会产生内存溢出异常。

java堆异常是实际应用常见的内存溢出异常情况。当出现JAVA堆内存溢出情况时,异常堆栈信息“java,lang.OutOfMemoryError” 跟着进一步提示“java heap space”。

使用内存分析工具对堆内存进行分析,次数使用的是Eclipse memory Analyzer 独立安装

测试代码

public class OomError {

    static class OOMObject{

    }

    public static void main(String[] args) {

        List<OOMObject> lists = new ArrayList<>();
        int i = 1;
        while (true){
            i++ ;
            if(i<1000000){
                lists.add(new OOMObject());
            }
            System.out.println("对象初始化完成");
        }
    }
}

内存泄漏分析:

JVM自动内存管理机制 二

由于GC Roots引用链的信息,对象没有被回收,通过分析可以准确定位内存泄漏代码的位置。

2、虚拟机栈和本地方法栈溢出

public class OomError {

    private int stackLen = 1;

    public void stackLeak(){

        stackLen ++ ;
        stackLeak();
    }

    public static void main(String[] args) {

        OomError oom = null;
        try{
             oom = new OomError();
            oom.stackLeak();

        }catch (Throwable e){

            e.printStackTrace();
            System.out.println("栈的最大深度"+oom.stackLen);
        }



    }
}

        }catch (Throwable e){

            e.printStackTrace();
            System.out.println("栈的最大深度"+oom.stackLen);
        }



    }
}

异常信息:

java.lang.StackOverflowError
	at com.haihang.exception.OomError.stackLeak(OomError.java:12)
	栈的最大深度16726

实验证明:在单线程下内存无法分配时,虚拟机都是抛出StackOverflowError异常。

多线程下,通过减少最大的堆和减少栈容量来换取更多的线程。

方法区和运行时常量池溢出

public class OomError {



    public static void main(String[] args) {
        //保持对象的引用防止GC
      List<String> lists =new ArrayList<>();
      int i=0;
      while(true){
          //intern 为本地方法,作用是先从常量池中查找字符,如果不存在将字符放入常量池
          lists.add(String.valueOf(i++).intern());
      }



    }
}

异常信息:

java.lang.OutOfMemoryError:Permgen space

在HotSpot虚拟机中Permgen space 属于堆中的永久代。

JVM自动内存管理机制 二

图片相同的代码逻辑返回的结果却是不一样,因为在jdk1.7以后的intern不在复制,只是在常量池中记录对象的引用,因此intern返回的引用于StringBuilder创建的字符串实例是同一个,所以相同;str2返回false的原因是“java”这个字符在执行toString之前已经出现过,不符合“首次出现”的原则,而计算机软件是首次出现的,因此返回true。

原文 

https://juejin.im/post/5b30831ff265da59a8365168

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » JVM自动内存管理机制 二

分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址