函数的调用过程与出入栈

本文详细介绍了Java虚拟机中函数调用的过程,涉及到Java栈的栈帧结构及其数据内容,包括局部变量表、操作数栈、动态链接和方法返回地址。栈帧在函数调用时被压入栈,函数结束时出栈,局部变量只在当前函数调用中有效。文章还讨论了栈上分配技术,通过逃逸分析判断对象是否在栈上分配,以提高性能。
摘要由CSDN通过智能技术生成

函数调用的过程

线程执行的基本行为是函数调用,每次函数调用的数据都是通过Java栈传递的。Java栈与数据结构上的栈有类似的含义,它是一块先进后出的数据结构,只支持入栈和出栈两种操作。Java栈的主要内容是栈帧。每次函数调用都会有一个对应的栈帧被压入Java栈,每次函数调用结束(无论是正常返回或者抛出异常),都会有一个栈帧被弹出Java栈。

如图所示,函数1中调用函数2,函数2中调用函数3,函数3调用函数4。函数1被调用,栈帧1入栈;函数2被调用,栈帧2入栈;函数3被调用,栈帧3入栈;函数4被调用,栈帧4入栈;函数4调用完毕,栈帧4出栈;函数3调用完毕,栈帧3出栈,一直到函数1出栈。

1565679392532

每次函数调用都会生成对应的栈帧,从而占用一定的内存。由于HotSpot虚拟机并不区分本地方法栈和Java栈,栈内存大小由-Xss参数设定。关于本地方法栈和Java栈,在Java虚拟机规范中定义了两种异常。

  • 线程的请求栈的深度大于虚拟机所允许的深度,将抛出StackOverflowError异常
public class StackDeepTest {

    private static int count = 0;

    public static void recursionCall() {
        count ++;
        recursionCall();
    }

    public static void main(String[] args) {
        try {
            recursionCall();        
        }catch(Throwable ex) {
            System.out.println("调用了:"+count);
            ex.printStackTrace();
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值