转载

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
正文到此结束
Loading...