JVM虚拟机栈StackOverflowError和OutOfMemoryError
-Xss是指设定每个线程堆栈大小,在JDK1.5之前栈容量默认是256K,之后的默认大小是1M;yaomingyangdeMacBook-Pro:~ yaomingyang$ java -XX:+PrintFlagsFinal -version |grepThreadStackSizeintx CompilerThreadStackSize=...
·
-Xss是指设定每个线程堆栈大小,在JDK1.5之前栈容量默认是256K,之后的默认大小是1M;
yaomingyangdeMacBook-Pro:~ yaomingyang$ java -XX:+PrintFlagsFinal -version |grep ThreadStackSize
intx CompilerThreadStackSize = 0 {pd product}
intx ThreadStackSize = 1024 {pd product}
intx VMThreadStackSize = 1024 {pd product}
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
关于虚拟机栈Java虚拟机规范中描述了两种异常:
- 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。
- 如果虚拟机在扩展栈时无法申请到足够的内存,则将抛出OutOfMemmoryError异常。
1.栈深度StackOverflowError异常测试
package controllers;
public class VMTest {
private int stackLength = 1;
public void stackLength() {
int a =1;
int b=2;
stackLength++;
stackLength();
}
public static void main(String[] args) {
VMTest vm = new VMTest();
try {
vm.stackLength();
}catch (Throwable e) {
System.out.println("栈深度是:"+vm.stackLength);
throw e;
}
}
}
Exception in thread "main" 栈深度是:17890
java.lang.StackOverflowError
at controllers.VMTest.stackLength(VMTest.java:11)
at controllers.VMTest.stackLength(VMTest.java:11)
- 使用-Xss参数减少栈内存容量,会抛出StackOverflowError异常,异常出现时输出的堆栈深度相应的缩小。
- 增大方法中的本地变量表的长度,结果抛出StackOverflowError异常,输出的堆栈深度相应的缩小。
TIPS:以上实验结果表明,在单线程下,无论是由于栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候都会抛出StackOverflowError异常。
2.虚拟机栈OutOfMemmoryError异常
Xss参数是设定虚拟机中每个线程占用的栈内存大小,而虚拟机栈可分配的内存又跟物理机的内存大小、Java堆内存、方法区等内存大小相关,其它的区分得的内存越大,虚拟机栈能够分得的内存就越小,并发的线程数量也就越小;而如果要想模拟OOM异常可以通过不停的创建线程,直到虚拟机栈内存被使用完。
如下程序会触发OOM异常,但是这个程序可能会导致操作系统假死,慎重测试(我的电脑就被搞死了,没办法强制重启)
package controllers;
public class VMOOTest {
public void statck() {
while(true) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
}
}
});
thread.start();
}
}
public static void main(String[] args) {
VMOOTest oo = new VMOOTest();
oo.statck();
}
}
TIPS:如果是建立过多线程导致内存溢出,在不能减少线程数量或者更换服务器内存的情况的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程。
更多推荐
已为社区贡献9条内容
所有评论(0)