本章主要讲解栈的分配参数的相关信息。
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:
最终结果:
可以看到执行了304次递归方法,并抛出java.lang.*Error栈溢出的异常。
然后我们将栈内存调整为256k:
最终结果:
可以看到执行了758次递归方法,并抛出java.lang.*Error栈溢出的异常。
这说明栈的大小决定了递归函数的深度,原因是因为栈需要存储每一次递归函数的局部变量以及内部参数,当有几千次递归的时候,栈内存就存储了几千次的局部变量以及参数,久而久之就会爆栈。所以一般出现java.lang.*Error栈溢出异常时,通常是因为程序调用的层数过深。
如果我们想要在有限的栈内存执行一定深度的递归函数,此时需要减少在递归函数中的局部变量数、内部参数数量,使得栈内存中的栈帧的局部变量表、以及成员变量参数空间压力小一些。
至此,有关Trace跟踪参数、堆的分配参数、栈的分配参数就讲解完毕了。当然,jvm的参数调整不仅仅是这些,剩下的参数在后面的jvm模块讲解中,会提到。
转载请注明出处:https://blog.csdn.net/acmman/article/details/80547512