堆溢出,栈溢出,内存泄漏,直接内存溢出以及异常信息整理

一、堆溢出
创建对象时如果没有可以分配的堆内存,JVM就会抛出OutOfMemoryError:java heap space异常。

堆溢出实例:

public static void main(String[] args) {
    List list = new ArrayList<>();
    int i=0;
    while(true){
        list.add(new byte[5*1024*1024]);
        System.out.println("分配次数:"+(++i));
    }
}

堆溢出,栈溢出,内存泄漏,直接内存溢出以及异常信息整理_第1张图片
二、栈溢出
栈空间不足时,需要分下面两种情况处理:

线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError
虚拟机在扩展栈深度时无法申请到足够的内存空间,将抛出OutOfMemberError
附:当前大部分的虚拟机栈都是可动态扩展的。

1、栈空间不足——StackOverflowError实例

public class errorTest02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//栈溢出之栈空间不足——StackOverflowError实例
		new errorTest02().test();

	}
	public void test(){
        test();
    }


}

堆溢出,栈溢出,内存泄漏,直接内存溢出以及异常信息整理_第2张图片
2、栈空间不足——OutOfMemberError实例
单线程情况下,不论是栈帧太大还是虚拟机栈容量太小,都会抛出StackOverflowError,导致单线程情境下模拟栈内存溢出不是很容易,不过通过不断的建立线程倒是可以产生内存溢出异常。

public class StackSOFTest {
 
    int depth = 0;
 
    public void sofMethod(){
        depth ++ ;
        sofMethod();
    }
 
    public static void main(String[] args) {
        StackSOFTest test = null;
        try {
            test = new StackSOFTest();
            test.sofMethod();
        } finally {
            System.out.println("递归次数:"+test.depth);
        }
    }
}

堆溢出,栈溢出,内存泄漏,直接内存溢出以及异常信息整理_第3张图片
三、内存泄露
内存泄漏是指在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。

import java.util.ArrayList;
import java.util.List;

public class Stack {
	private static List list = new ArrayList();
	private static int count = 0;
	public static void main(String[] args) throws InterruptedException {
	System.out.println("申请前的可用内存 = "+getFreeMemory());
	while(true){
	list.add(new byte[1024*1024]);//用实例变量申请1M内存,当方法执行完毕时,这个static的变量是不会被释放
	count++;
	if (count % 100 == 0) {
	System.out.println("当前list.size()="+list.size()+",可用内存 = "+getFreeMemory());
	Thread.sleep(500);
	}
	}
	}
	public static long getFreeMemory() {
	return Runtime.getRuntime().freeMemory() / (1024 * 1024);
	}
}

堆溢出,栈溢出,内存泄漏,直接内存溢出以及异常信息整理_第4张图片
四、直接内存溢出
JVM虚拟机是运行在操作系统上的进程,操作系统分配给JVM的内存在启动是有限的,不可能把全部内存都分配给JVM,Java NIO又用到了直接内存技术,利用Channel和Buffer直接操作JVM外的内存,避免数据在JVM和操作系统内存之间来回复制。但是,当JVM和直接内存的和大于操作系统总内存时,就会发生内存溢出。
堆溢出,栈溢出,内存泄漏,直接内存溢出以及异常信息整理_第5张图片

总结:
栈内存溢出:程序所要求的栈深度过大。
堆内存溢出: 分清内存泄露还是内存容量不足。泄露则看对象如何被 GC Root 引用,不足则通过调大-Xms,-Xmx参数。
内存泄漏:内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)
直接内存溢出:是指程序在申请内存时,没有足够的内存空间供其使用。
参考:https://blog.csdn.net/oqkdws/article/details/83412885

你可能感兴趣的:(Java)