深入JVM 虚拟机栈和本地方法栈溢出

由于在HotSpot虚拟机中不区分虚拟机栈和本地方法栈,因此,对于HotSpot而言,-Xoss设置本地方法栈的参数失效

,栈的容量大小只有Xss参数设置。虚拟机栈主要出现2种错误异常

  • 如果线程请求的栈深度大于虚拟机栈所允许的最大深度,抛出StackOverFlowError错误异常
  • 如果虚拟机栈在拓展栈时无法申请到足够的内存空间,抛出OutOfMemoryError错误异常

实验限制于单线程中进行,获得了StackOverFlowError的错误异常

 

VM Args: -Xss 128k 设定栈空间上限128k

不断递归调用一个函数,记录递归深度

 

public class JVM_StackOverFlow {
	
	/*
	 * 
	 * VM Args: -Xss 128k
	 * 
	 * 
	 */

	public static void main(String[] args) throws Throwable{
		// TODO Auto-generated method stub
		
		stack_sof oom=new stack_sof();
		try
		{
			oom.stackleak();
		}catch(Throwable e)
		{
			System.out.println("stack length"+oom.stacklength);
			throw e;
		}
		
		

	}

}

class stack_sof
{
	public int stacklength = 1;
	public void stackleak()
	{
		stacklength++;
		stackleak();
	}
}


运行结果 

 

深入JVM 虚拟机栈和本地方法栈溢出_第1张图片

 

结果表明:在单个线程下,无论是由于栈帧太大还是虚拟机容量太小,当内存无法分配时,虚拟机抛出StackOverFlowErrer的错误异常。

操作系统分配给每个进程的内存是有限的,如32为windows限制是2GB

虚拟机提供参数来控制堆(-Xmx -Xms)和方法区最大值,程序计数器占用很小,可忽略不计,在加上虚拟机本身的运行所占内存,剩下内存被虚拟机栈和本地方法栈瓜分,而这又是线程私有的,那么每个线程分配的空间被进一步压缩,导致内存耗尽,尤其在多线程并发程序中。

 

 

 

 

 

 

你可能感兴趣的:(Java进阶,深入理解Java虚拟机)