内存泄露和内存溢出的区别

一、内存泄露

由于不能正常进行垃圾回收,占用的内存一直不会被清除,例如:拥有一块20字节的内存空间,你将30字节的文件写入其中,就会造成内存溢出。由于内存泄漏,最终会导致内存溢出(OOM),导致系统崩溃

二、内存溢出

是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

1. 栈内存溢出(StackOverflowError)

public class Test001 {
    public static void main(String[] args) {
        Test001 test001 = new Test001();
        test001.testMethod();
    }
    public void testMethod(){
        testMethod();
    }
}

递归调用方法,导致栈内存溢出,学过jvm我们可以知道,虚拟机栈是用于描述java方法执行的内存模型,一个方法从开始执行到执行完毕就对应该栈帧的入栈到出栈的过程,由于递归,一层嵌套一层,导致方法执行不完,只有入栈没有出栈,导致栈内存溢出。

2. 堆内存溢出(OutOfMemoryError:java heap space)

public class Test001 {
   private List<String> list = new ArrayList<>();
    public static void main(String[] args) {
        Test001 test001 = new Test001();
        while (true){
            test001.list.add(UUID.randomUUID().toString());
        }
    }
}

在创建新的对象时, 堆内存中的空间不足以存放新创建的对象时发生。产生原因:程序中出现了死循环,不断创建对象;程序占用内存太多,超过了JVM堆设置的最大值。

3. 永久代溢出(OutOfMemoryError:PermGen sapce)

持久带中包含方法区,方法区包含常量池

因此持久带溢出有可能是运行时常量池溢出,也有可能是方法区中保存的class对象没有被及时回收掉或者class信息占用的内存超过了我们配置

用String.intern()触发常量池溢出

Class对象未被释放,Class对象占用信息过多,有过多的Class对象。可以导致持久带内存溢出

 

posted @ 2022-06-09 21:56  yifanSJ  阅读(106)  评论(0编辑  收藏  举报