【Java虚拟机探究】5.常用JVM配置参数-栈的分配参数

时间:2022-12-27 14:06:37
在使用JVM编译java时,都会去设置相关的参数(例如使用eclipse的时候,可以设置eclipse的eclipse.ini文件来对jvm做一些参数配置)。jvm的参数设置主要涉及到三种,分别是Trace跟踪参数、堆的分配参数、栈的分配参数。

本章主要讲解栈的分配参数的相关信息。
1.栈大小分配
分配参数:-Xss
特点:
(1)局部变量、参数都分配在栈上。
(2)栈的内存通常只有几百k,但是它决定了函数调用的深度;如果程序使用了很深的递归函数,而栈内存又非常小,此时很有可能发生栈溢出(java.lang.*Error)的情况。
(3)每一个线程都有独立的栈空间。如果想尽量多跑一些线程的话,就尽量将栈内存缩小,而不是增大。

下面是一段递归函数的调用:
public class TestStackDeep {
	private static int count = 0;
	
	public static void recusion(long a,long b,long c){
		long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10;
		count++;
		recusion(a,b,c);
	}
	
    public static void main(String[] args) {
    	try {
			recusion(0L,0L,0L);
		} catch (Throwable e) {
			System.out.println("deep of calling = "+count);
			e.printStackTrace();
		}
	}
}
在该段代码中,我们的递归函数每一次都会记录调用的次数,当发生栈溢出的异常时,catch该异常,然后打印出一共递归的层数。
首先我们将栈内存调整为128k:
【Java虚拟机探究】5.常用JVM配置参数-栈的分配参数
最终结果:
【Java虚拟机探究】5.常用JVM配置参数-栈的分配参数
可以看到执行了304次递归方法,并抛出java.lang.*Error栈溢出的异常。

然后我们将栈内存调整为256k:
【Java虚拟机探究】5.常用JVM配置参数-栈的分配参数
最终结果:
【Java虚拟机探究】5.常用JVM配置参数-栈的分配参数
可以看到执行了758次递归方法,并抛出java.lang.*Error栈溢出的异常。
这说明栈的大小决定了递归函数的深度,原因是因为栈需要存储每一次递归函数的局部变量以及内部参数,当有几千次递归的时候,栈内存就存储了几千次的局部变量以及参数,久而久之就会爆栈。所以一般出现java.lang.*Error栈溢出异常时,通常是因为程序调用的层数过深。
如果我们想要在有限的栈内存执行一定深度的递归函数,此时需要减少在递归函数中的局部变量数、内部参数数量,使得栈内存中的栈帧的局部变量表、以及成员变量参数空间压力小一些。

至此,有关Trace跟踪参数、堆的分配参数、栈的分配参数就讲解完毕了。当然,jvm的参数调整不仅仅是这些,剩下的参数在后面的jvm模块讲解中,会提到。

转载请注明出处:https://blog.csdn.net/acmman/article/details/80547512