精华内容
下载资源
问答
  • 局部变量是在栈中分配内存吗
    千次阅读
    2020-11-02 18:58:53

    成员变量在堆内存里,局部变量在栈内存里。(基础类型)

    我有疑惑:

    既然成员变量存在于对象中,对象存在于堆中,所以成员变量存在于堆中。那么按照这样的推理,局部变量存在于方法中,而方法存在于对象中,对象存在于堆中,那是不是可以说局部变量存在于堆中?

    解决思想

    当对象new出来,实体存在于堆,对象的成员变量已经在堆上分配空间,但对象里面的方法是没有出现的,只出现方法的声明,方法里面的局部变量并没有创建。等到对象调用此方法时,为了加快运行的速度,方法中的局部变量才会在栈中创建,所以,方法中的局部变量是在栈内的。

    当然需要注意的是类变量(静态变量)存在于方法区!!引用类型的局部变量声明在栈,存储在堆

     

    内存:栈 1.存放局部变量 2.不可以被多个线程共享 3.空间连续,速度快
    堆 1.存放对象 2.可以被多个线程共享 3.空间不连续,速度慢,但是灵活 
    方法区 1.存放类的信息:代码、静态变量、字符串常量等等 2.可以被多个线程共享 3.空间不连续,速度慢,但是灵活

    总的来说:我们先来记住两条黄金法则:
    1.引用类型总是被分配到“堆”上。不论是成员变量还是局部
    2.基础类型总是分配到它声明的地方:成员变量在堆内存里,局部变量在栈内存里。

    更多相关内容
  • 首先说明,"Java中的基本数据类型一定存储在栈中的吗?”这句话肯定是错误的。...栈内存中局部变量随着方法的消失而消失。 成员变量存储堆中的对象里面,由垃圾回收器负责回收。 如以下代码: ...

    "Java中的基本数据类型一定存储在栈中的吗?”

    这句话肯定是错误的。

    对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。 形式参数是局部变量,

    局部变量中基础数据类型的引用和值都存储在栈中,对象引用存在栈中,栈内存中的局部变量随着方法的消失而消失。

    对象存在堆中。 成员变量存储在堆中的对象里面,由垃圾回收器负责回收。

    在方法内的局部变量是基本数据类型的话那么运行时存储在栈stack(java虚拟机栈)中,若是对象,则引用分配在内存栈stack(java虚拟机栈)中,对象实例分配到堆内,

    类的成员变量 ,无论是基本类型还是其它类型,因为整个实例对象都被分配到堆heap中,因此成员变量也在堆heap类了

    如以下代码:

     

    class BirthDate {
        private int day;
        private int month;
        private int year;
    
        public BirthDate(int d, int m, int y) {
            day = d;
            month = m;
            year = y;
        }
        // 省略get,set方法………
    }
    
    public class Test {
        public static void main(String args[]) {
            int date = 9;
            Test test = new Test();
            test.change(date);
            BirthDate d1 = new BirthDate(7, 7, 1970);
        }
    
        public void change(int i) {
            i = 1234;
        }
    }

    对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:

    1.main方法开始执行:int date = 9; date局部变量,基础类型,引用和值都存在栈中。

    2.Test test = new Test();test为对象引用,存在栈中,对象(new Test())存在堆中。

    3.test.change(date); i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。

    4.BirthDate d1= new BirthDate(7,7,1970); d1为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。

    5.main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(), new BirthDate()将等待垃圾回收。

    展开全文
  • 目录 1、java中的变量与数据类型 ...所以变量的内存分配可以看成两个不部分:1、变量在内存中分配(“变量分配”) 2、变量所引用的数据在内存中分配(“数据分配”) 1.1、变量类型有: 局部.

    目录

    1、java中的变量与数据类型

    2、思考

    3、例子:

    3.1、分析:

    3.2、结论


    1、java中的变量与数据类型

    变量是一个容器,用来装什么的呢?装内存地址,这个内存地址对应的是内存中某个数据。
    那为什么这个容器不直接装这个数据更简洁呢?因为直接装数据的话,这个数据就无法被别的变量使用,无法复用就会导致很多不便。
    所以变量的内存分配可以看成两个不部分:1、变量在内存中的分配(“变量分配”) 2、变量所引用的数据在内存中的分配(“数据分配”)

    1.1、变量类型有:

    局部:在方法内声明的变量
    实例:在类中但在方法外声明并且没有static
    静态:声明为static的变量

    1.2、变量的数据类型有:

    1、原始数据类型 2、引用数据类型

    2、思考

    原始数据类型变量的“变量分配”和“数据分配”是在一起的(都在方法区或栈内存或堆内存,这里思考什么时候在方法区、什么时候在栈内存、什么时候在堆内存???)
    引用数据类型的“变量分配”和“数据分配”不一定是在一起的(什么情况是在一起的?什么情况不在一起?)

    3、例子:

    public class Fruit {
    
     private static int x = 10;
     static BigWaterMelon bigWaterMelon_1 = new BigWaterMelon(x);
    
     private int y = 20;
     private BigWaterMelon bigWaterMelon_2 = new BigWaterMelon(y);
    
    public static void main(String[] args) {
        Fruit fruit = new Fruit();
        int z = 30;
        BigWaterMelon bigWaterMelon_3 = new BigWaterMelon(z);
    
    
        new Thread() {
            @Override
            public void run() {
                int k = 100;
                setWeight(k);
            }
    
            void setWeight(int waterMelonWeight) {
                fruit.bigWaterMelon_2.weight = waterMelonWeight;
                System.out.printf(fruit.bigWaterMelon_2.weight + "");
            }
    
        }.start();
    }
    }
    
    class BigWaterMelon {
    
     int weight;
    
     BigWaterMelon(int weight) {
        this.weight = weight;
     }
    }
    

    3.1、分析:

    栈:

    1、栈内存中按线程粒度来划分区域。

    比如划分为:主线程、new Thread线程、其他线程等等

    2、每个线程区域中又按方法粒度来划分区域。

    比如:主线程区域中划分了一块区域:main();new Thread线程中划分了两块区域:setWeight()、run()

    3、每块方法区域中包含其所有的局部变量。

    比如main()方法这块区域中包含局部变量:String[] args、Fruit fruit、int z = 30、BigWaterMelon bigWaterMelon_3
    这里可以看到String[] args、Fruit fruit、BigWaterMelon bigWaterMelon_3这三个局部变量在这里只存储了变量,而没有存放变量的数据,而int z = 30既存放了变量int z 也存放了变量的数据30。这就可以肯定上面的第一条结论“栈内存中,基本数据类型的变量和变量的数据是存放在一起的”,这里要注意:只是说存放在一起,但没说是一起在栈内存,也可能一起在堆内存或者方法区,继续往下分析。

    方法区:

    1、方法区中按class粒度来划分区域。(所以方法区存储的都是只加载一次的)

    比如:Fruit.class、BigWaterMelon.class、Fruit$1.class(这是个什么玩意?后面解释)

    2、在每块class区域中包含其所有的静态变量。(所以方法区存储的都是只加载一次的)

    比如:Fruit.class中包含static int x = 10、static BigWaterMelon bigWaterMelon_1。这里又出现了基本数据类型,和在栈内存中一样,基本数据类型的变量和变量的数据存放在一起,和栈内存中唯一不同的是,栈内存中是局部变量,而方法区中是静态变量。

    堆:

    1、堆内存中按实例和其所包含的非静态变量划分区域。

    比如:
    1、new String[] 对应的变量是栈内存中的 : String[] args;
    2、new BigWaterMelon()+int weight = 10 对应的变量是方法区中 :static BigWaterMelon bigWaterMelon_1;
    3、new BigWaterMelon()+int weight = 30 对应的变量是栈内存中 :BigWaterMelon bigWaterMelon_3;
    4、new Fruit()+int y = 20+BigWaterMelon bigWaterMelon_2 对应的变量是 栈内存中 :Fruit fruit;
    5、new BigWaterMelon()+int weight = 20 对应的变量是同在堆内存中的 : BigWaterMelon bigWaterMelon_2;
    6、new Fruit$1() 没有对应变量,因为它是匿名的,在方法区中存在它的类文件Fruit$1.class(这是个啥东西往下看)

    前面一直搞不明白Fruit$1.class这是个什么玩意,找编译后的文件看一下:

    其实就是一个Thread类。。。只是因为我们用了匿名对象,所以给我们生成了一个这么个玩意,那如果我们把new Thread放在别的类中试试会怎么样,新建一个Test.class如图:

    为了简介,我把Thread对象中所有东西都注释了。在编译后得到:


    打开看看:


    果然就是一个Thread类,所以匿名对象其实会生成一个class文件,类名就是由匿名对象存在的类名字后面加$和数字拼成。原谅我的基础辣鸡。。。
    好了,重新描述一下上面堆内存的第六条就可以这么说:
    6、new Fruit$1()(即new Thread()) 没有对应变量,因为它是匿名的,在方法区中存在它的类文件Fruit$1.class。
    这下就好理解了。
    我们在回头看Fruit$1.class文件,可以看到他有一个构造函数:


    Fruit$1(Fruit paramFruit) {}
    所以在堆内存中的形式应该是new Fruit$1()(即new Thread())+Fruit paramFruit,其中Fruit paramFruit变量对应的实例就是堆中的第4条。

    注意⚠️:

    同一种颜色代表变量和对象的引用关系

    由于方法区和堆内存的数据都是线程间共享的,所以线程Main Thread,New Thread和Another Thread都可以访问方法区中的静态变量以及访问这个变量所引用的对象的实例变量。

    栈内存中每个线程都有自己的虚拟机栈,每一个栈帧之间的数据就是线程独有的了,也就是说线程New Thread中setWeight方法是不能访问线程Main Thread中的局部变量bigWaterMelon_3,但是我们发现setWeight却访问了同为Main Thread局部变量的“fruit”,这是为什么呢?因为“fruit”被声明为final了。

    当“fruit”被声明为final后,“fruit”会作为New Thread的构造函数的一个参数传入New Thread,也就是堆内存中Fruit$1对象中的实例变量val$fruit会引用“fruit”引用的对象,从而New Thread可以访问到Main Thread的局部变量“fruit”。
     

    3.2、结论

    3.2.1、“变量的分配”:

    局部变量在栈内存,静态变量在方法区,实例变量在堆内存。 也就是三个内存中都有变量。

    3.2.2、“数据的分配”:

    原始数据类型跟随自己的“变量分配”在一起,相亲相爱。
    引用数据类型在堆内存中。

    4、补充

    栈空间:由JVM自动分配释放的一块内存空间 ,用于存放函数的参数值,局部变量值等,其工作原理遵循数据结构中栈”后进先出“的原则。

    方法的栈帧:在方法被调用时JVM在栈空间的栈顶为此方法分配一块内存空间(该空间也称为:该方法的栈帧)(入栈),其中存放着该方法的数据信息(局部变量等),当该方法执行完毕,会自动将此栈帧弹出(出栈),其中的数据信息会被自动销毁。

    1、解释说明

    *测试代码如下:

    public class test {
        public static void main(String[] args) {
            System.out.println("main方法操作一");    
            function();
            System.out.println("main方法操作二");
        }
        private static void function(){
            int a=1;
            System.out.println("function方法"+a);    
        }
    }

    2、画图分析执行流程以及栈帧的作用

    3、堆空间:由程序员分配释放,创建对象就是为对象分配堆空间,当对象失去引用时,可能由Java的GC垃圾回收器回收。

    4、方法区:保存在着被加载过的每一个类的信息;这些信息由类加载器在加载类的时候,从类的源文件中抽取出来;static变量信息也保存在方法区中;

    5、基本数据类型:Java的八大基本数据类型。

    6、引用数据类型:Java的类类型、接口类型、数组类型。

    其中枚举类型和注解类型属于特殊的类类型;
    字符串属于数组类型(因为String底层就是一个char数组);
    7、成员变量:定义在类中方法(代码块)外的变量。

       使用static修饰的成员变量: 静态成员变量位于方法区中(详细请看下文),是类级别的。
       未使用static修饰的成员变量:实例成员变量位于堆空间中(详细请看下文),是对象级别的。
    8、局部变量 :除成员变量外都是局部变量位于方法所在的栈帧中(详细请看下文),是方法级别的。

    二、变量的存储方式

    1、局部变量
    局部变量在方法被调用时执行到初始化语句时被创建。
    作用区域为初始化后到方法(或语句块)结束。
    基本类型的局部变量:在方法调用时执行到该变量的初始化语句时直接将该变量的值保存到该方法的栈帧中。

    在这里插入图片描述

    引用数据类型局部变量:在方法调用时将引用的堆内存中的值的地址保存到该变量到的栈内存中。

    在这里插入图片描述

    上面的方法执行完毕后,堆空间中的Person对象就失去了引用,等待着GC自动回收。
    2、成员变量
    实例成员变量:
    实例成员变量在使用new关键字创建对象时被创建并带有默认的初始值(基本类型对应基本类型的初始值,引用类型默认值为null)。

    局部变量是没有初始值的,必须初始化后才能使用。

    在这里插入图片描述
    上图中Person对象的实例成员变量是i和stu位于堆空间中,stu为引用类型成员变量,又引用了另一个堆空间中的对象,p为main方法中的局部变量。

    静态成员变量(类成员变量):
    类成员变量随着字节码文件的加载而被加载,当JVM将Person.class加载进内存时静态成员变量就存在了,和字节码一样,位于一块叫做方法区的内存空间中,类成员变量被该类的所有对象所共享。

    在这里插入图片描述

    三、总结(表格)

    变量类型

    代码中的位置生命周期开始生命周期结束内存中的位置
    局部变量方法中,方法形参,代码块中执行到初始化语句时所在的方法代码块结束时栈空间
    实例成员变量类中对象创建时对象被GC回收堆空间
    类成员变量类中(使用static修饰)所在类的字节码被加载进内存时JVM停止运行时方法区
    展开全文
  • 局部变量内存分配可能在栈上也可能堆上 堆和的简单说明: 1.(操作系统):由操作系统自动分配释放 2.堆(操作系统): 一般由程序员分配释放,例如c/c++golang,java,python有自动的垃圾回收机制 ...
  • 1、区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与...
  • 现在我们就可以总结一下下:局部变量在栈根据声明顺序从上至下分配空间,VS2019两个变量之间空2个字节的空间。 但是,别的编译器下也是空2个字节吗?下面Linux下的gcc编译器下测试一下上面的代码: ...

    众所周知, 由c/c++编译的程序占用的内存有四个分区,分别是堆区栈区(又称堆栈)、静态区只读区

    其中堆区存放新出炉的数据;栈区存放局部变量、形参等;静态区存放全局变量和静态变量;只读区存放常量(其中包括const修饰的变量)。

    而我们下面要讨论的则是局部变量在栈区中的存储。

    需要注意,不同编译器下的存储方式是不同的。这里主要用VS2019分析


    先看两段代码:

    第一段代码:
    int main()
    {
    	int a = 10;
    	int b = 20;
    	int* p = &a;
    	printf("%d", *(p - 3));
    	return 0;
    }
    第二段代码:
    int main()
    {
    	int i = 0;
    	int arr[10] = { 0 };
    	for (i = 0; i <= 12; i++)
    	{
    		arr[i] = 0;
    		printf("第%02d次打印\n", i);
    	}
    	return 0;
    }

    让我们看看在VS2019中它们的运行结果:

    第一段:

    第二段:

    可以看到,第一段代码对(p - 3)解引用打印出来的是b的值;而第二段代码虽然越界访问了,但竟然陷入了死循环!这是为什么呢?


     为了解释上面两个问题,我们首先要了解栈区的存放规则:

    我们把栈区分成一个个小空间,当VS2019编译器在栈区存放局部变量的时候,先存放的变量放在上面,后声明的变量依次向下存放。但是,两块空间之间有没有空内存呢?

     我们可以通过调试来进行观察:

    可以看到,a的地址和b的地址之间差了两个字节的空间:

    两个变量之间是每次都空两个字节还是随机空的呢?在VS2019中,两个变量是固定空两个子节的。在其他编译器中则会有不同,后面会对gcc编译器进行举例。


    了解了这些,我们就能分析上面两段代码是怎么执行的了:

    对于第一段代码,p指向的是a的地址,根据上面的图我们可以直观判断出p - 3指向的就是b的地址,所以对p - 3解引用找到的实际上是b

    对于第二段代码,执行逻辑同上,arr[0]是数组第一个元素的地址,以此类推,arr[9]就是数组最后一个元素的地址,那越界访问的arr[10]呢?是随机的一个地址还是arr[9]后面的一块字节空间?我们通过调试看一下:

    可以看到arr[10]确实是arr[9]后面一个字节的空间。数组的存储是根据下标的增加依次向上开辟空间的,那么iarr[9]之间就差了两个字节的空间,所以...存放arr[12]的地址不就是存放i的地址了嘛!如果编译器敢越界访问操作,等循环到i=12的时候,修改arr[12]的值不就是修改i的值了嘛!嘿!还真是这样!所以当循环到第12次的时候,i就被赋成0了,所以我们观察第2段代码的运行结果会发现,打印完“第11次打印”的字样后接着打印的就是“第0次打印”。


    现在我们就可以总结一下下:局部变量在栈区中根据声明顺序从上至下分配空间,在VS2019中两个变量之间空2个字节的空间。

    但是,在别的编译器下也是空2个字节吗?下面在Linux下的gcc编译器下测试一下上面的代码:

    可以看到,p存放的是a的地址,而p+1存放的则是b的地址,与VS2019中的存放规则完全不同!

    另外,我们再看下边一行代码:

    通过上面两段代码我们很容易发现:单变量的存储是按声明顺序从低地址到高地址依次存储的!

    展开全文
  • RAM中局部变量在栈中分配

    千次阅读 2016-09-28 18:42:15
    无OS时,RAM的使用可以分为数据、和堆区域;有OS时,将RAM分成若干个段,每个任务分配一个段,用于各自的数据、和堆区域。... 编译器局部变量分配空间时通常有两种做法:使用寄存器和使用。寄存
  • 【应用C】局部变量空间分配

    千次阅读 2019-01-14 22:15:03
    有时候,C语言的循环,如果编程时对边界判断错误,就会带来意想不到的结果,小白本文提及一个有趣的C语言问题,此问题并不是小白原创,而是一本编程书的考核内容,小白将其分享到此。 C语言有趣的...
  • C语言局部变量在内存栈中的顺序

    千次阅读 2017-08-23 20:44:10
    规则1:内存由低到高优先分配给占位8字节、4字节、2字节、1字节的数据类型 数据类型占位说明: 8字节:double、longlong int 4字节:int、float、long int、unsigned int 2字节:short 、unsigned short
  • C++ 在栈分配内存

    千次阅读 2020-01-02 09:44:09
    malloc与alloc的区别 malloc()与 alloc() ...执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配...
  • 局部变量内存分配详解

    千次阅读 2018-04-28 15:48:41
    局部变量在内存栈中是怎样存储的? 会有数据对齐吗? 带着这个思考做了个小测试,如上代码,打印结果如下 [wu.heshi@buildserver endian]$ ./a.out  0xdb53c19c 0xdb53c19b 0xdb53c194 0xdb53c193 如果不理解为什么...
  • C语言在内存中一共分为如下几个区域,分别是:1.内存区:存放局部变量名;2.内存堆区:存放new或者malloc出来的对象;3.常数区:存放局部变量或者全局变量的值;4.静态区:用于存放全局变量或者静态变量;5.代码区...
  • C语言定义的静态变量存放在栈区,动态分配内存空间位于堆区。 这题答案为 F 为大家科普一下知识 C语言中局部变量存在里,全局变量存静态存储区。 局部变量在栈空间上分配,这个局部变量所在的函数被多次...
  • 一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 区(stack) ...当我们声明变量时,那么编译器会自动接着当前区的结尾来分配内存。 堆区(heap) 一般由程序员...
  • 成员变量内存里,局部变量在栈内存里。(基础类型) 我有疑惑: 既然成员变量存在于对象,对象存在于堆,所以成员变量存在于堆。那么按照这样的推理,局部变量存在于方法,而方法存在于对象,对象存在...
  • 全局变量和局部变量在内存里的区别?堆和 转:一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等...
  • 太无耻了吧,都没给别人分,,,, 程序局部变量是编译时候分配地址的还是运行时分配的呢?...按照我的理解,局部变量在栈中分配的,应该是运行时分配地址的,不知道对不对? 是一种先进后出的数据...
  • 根据“Java中的变量与数据类型”中的介绍,“变量在内存中分配的保留区域的名称。换句话说,它是一个内存位置的名称”,也就是说我们通过这个变量名字就可以找到一个指向这个变量所引用的数据的内存指针,根据变量...
  • 目录一、需要了解的知识点二、变量的存储方式1、局部...方法的栈帧:方法被调用时JVM在栈空间的栈顶为此方法分配一块内存空间(该空间也称为:该方法的栈帧)(入栈),其中存放着该方法的数据信息(局部变量等),当该...
  • 1、区(stack)——程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等,程序结束时由编译器自动释放。 2、堆区(heap)——在内存开辟另一块存储区域。一般由程序员分配释放, 若程序员不释放,程序...
  • 局部变量只是自己用,放在数据段纯属浪费空间,没有必要,故将其放在自己的栈中,随时可以清理,真正体现了局部的意义。 这个就是堆栈框架,由于是向下生长的,堆栈框架就是把esp指针提前加一个数,原esp...
  • 全集变量、局部变量、静态全局变量、静态局部变量在内存中如何存储,有什么区别,和堆的区别,这都是C/C++的基础问题。各种招聘笔试面试中,经常都能够遇到与之相关的问题。前些日子我看了一些与之相关的文章,...
  • 一、内存基本构成 可编程内存在基本上分为...区:执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的...
  • 形式参数是局部变量局部变量的数据存在于栈内存中栈内存中局部变量随着方法的消失而消失。 成员变量存储堆中的对象里面,由垃圾回收器负责回收。 如以下代码:class BirthDate { private int day; ...
  • 形式参数是局部变量局部变量的数据存在于栈内存中栈内存中局部变量随着方法的消失而消失。 成员变量存储堆中的对象里面,由垃圾回收器负责回收。 如以下代码: class BirthDate { private int day; ...
  • 静态局部变量保存全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。该变量全局数据区内分配内存;静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行...
  • 讨论函数的形参变量时曾经提到,形参变量被调用期间才分配内存单元,调用结束立即释放。这一点表明形参变量只有函数内才是有效的,离开该函数就不能再使用了。这种变量有效性的范围称变量的作用域。不仅对于...
  • 局部变量分配的内存在里:大小与编译器有关。默认情况下,visual studio 2010 的大小为1M。 全局变量存放静态存储区:对于全局变量来说,与编译器有关,默认情况下, VS2010可容纳的全局变量数组大小是2G...
  • C 语言,通常可以把内存理解为四个分区:、堆、全局/静态存储区和常量存储区。 (stack,也称“堆栈”) 通常是用于存储编译期间就能确定存储大小的变量,用于函数作用域内创建,离开作用域后自动...
  • 栈帧存储了方法的局部变量表、操作数、动态连接和方法返回地址等信息。每一个方法从调用至执行完成的过程,都对应着一个栈帧虚拟机里从入栈到出栈的过程。 一个线程方法的调用链可能会很长,很多方法都同时...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 175,188
精华内容 70,075
关键字:

局部变量是在栈中分配内存吗