一、虚拟机和本地方法Java栈溢出
StackOverflowError:
如果线程请求的栈深度大于虚拟机所允许的最大深度,会抛出StackOverFlow异常(比如递归的时候不写出口)
//单线程状态下
public class Test2 {
private int length = 1;
public void testLength(){
length++;
testLength();
}
public static void main(String[] args) {
Test2 test2 = new Test2();
try {
test2.testLength();
}catch (Throwable e){
System.out.println(test2.length);
System.err.println("栈溢出");
}
}
}
注:如果是因为多线程导致的内存溢出问题,在不能减少线程数的情况下,只能减少最大堆和减少栈容量的方式来换取更多线程
二、 Java堆溢出
OOM(OutOfMemoryError):
Java堆用于存储对象实例,只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免来GC清除这些对象,那么在对象数量达到最大堆容量后就会产生内存溢出异常。
简单来说就是:如果虚拟机在拓展栈时无法申请到足够的内存空间,则会抛出OOM异常。
产生的原因:
- 内存溢出:当前堆的空间过小,没有足够空间容纳新的对象。
解决方法:适当的将堆的内存扩大,或者检查对象生命周期是否过长就基本可以解决问题。 - 内存泄露:产生的对象永远无法被垃圾回收。
//内存泄露
public class Test {
static class OOMObject{}
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<OOMObject>();
while(true)
list.add(new OOMObject());
}
}