java虚拟机栈番外篇
晋-陶渊明《五柳先生传》:[好读书,不求甚解],原指读书只求领会主旨,不死抠字眼。现多指满足于了解个大概,不作深入理解。
不求甚解,好吗?
在上一篇文章讲解java虚拟机栈的时候,我有一个困惑的问题,大概是:
比如int a = 5,那么它是如何存储的,我们先来看这个代码,int代表基本数据类型整型,a可以叫做一个变量,更加准确的来说,它是一个变量名称a,这个a是我们程序员编写代码的时候写给我们自己看的,然后给这个变量赋值5,这个5就是具体的变量值了。
那么当其编译,并加载到内存的时候发生了什么呢?我们一步步来,首先就是会向内存申请分配一块内存,这块内存多大呢?因为int是占四个字节,也就是32位,所以应该向内存分配一个32内存大小的空间,然后将这个5转换成二进制,然后存在这个32位的空间。
我们继续深入,我们知道了内存大小空间,那么我们这里只说向内存申请分配空间,那么是什么内存呢?我们知道jvm内存空间有好几个区域,嗯,这个我们也知道,是栈内存空间。
那么这个栈内存空间又是什么呢?这个栈准确来说十java虚拟机栈,是随线程而生,而这个java虚拟机栈中随着方法的调用又会产生一个栈帧随之入栈,然后由方法的结束进而出栈,而这个栈帧中又包含着局部变量表,操作数栈,动态链接和方法返回地址等。
那么我们说它存储在栈内存中,而这个java虚拟机栈又有这么几部分,那么它到底是存放在哪呢?局部变量表?还是操作数栈,亦或者是其他。首先我们来看,这个局部变量表是存放什么的?
局部变量表是用来存放方法运行的参数和方法内部定义的局部变量,那好,现在我们的这个int a = 5就是定义在一个方法内的,那么它自然是一个局部变量,这么一来就是存放在局部变量表了,不过,存放在局部变量表的到底是这个a还是5呢?
好了,到这里就是我的疑问了!
对于这个5倒是好理解,就是一个具体的数值,存放的话是将其转成二进制数据存放在相应的内存空间,那么这个a是什么?从字面意思上看就是一个字母a,我们之所以定义这个a,大概就是给这个变量起个名字,当我们说a的时候,我们就知道指的就是这个5,这就好比你叫张三,我们叫张三其实指的就是你这个具体的人。
那么,关乎到存储的话又是怎么回事呢?比如这有一片住宅区,有几间房子,然后给你“张三”分配一间房子,你住进去了,实际上住进去的是你这个人,这就好比现在我们在局部变量表(住宅区)申请一块内存(一间房子),然后将这个5(你这个人)存进去,而这个a(你的名字张三)就代指这个5(你这个人)。
这个时候我们可能会说,“那个那个,,张三,你的房子”,对我们会说张三的房子,要是给这个房子打上一个标签,那就是“张三的”,给这个房子起个名字的话,对,就叫“张三”
也就是说对于int a = 5,要存储了,来来来,赶紧在局部变量表中申请一块内存,把这个5放进去,那这块内存空间做个标识吧,叫啥呢?嗯,就叫做a。
这是基本数据类型,那如果是引用数据类型呢?比如String s = new String()
那么这个是存么存储的呢?我门知道对象实例是存放在堆内存,也就是在堆中申请一块内存空间存放这个字符串对象实例,那么这里的这个s是怎么回事呢?这个时候也会在栈内存中申请一块内存空间,存储啥呢?存储存放堆中字符串实例对象那一块内存空间的首地址,而在这栈中申请的这块内存空间你就可以看做是s。
也就是说对于基本数据类型是在栈内存空间申请内存空间存放具体的数值,这块内存空间我们怎么去表示它,就可以用具体的变量名称去表示,而对于引用数据类型, 在栈中申请的这块内存空间存放的则是实例对象在堆中所在内存空间的首地址,而这个栈中的这块内存就可以用对象引用表示!
像int a = 5和String s = new String()中的a和s(又叫做对象引用)都是一个名称,我们上面所说用这些名称来表示栈中分配的内存空间,但是要说这些名称到底是个什么玩意,我觉得他们实际上是这些栈中分配的内存空间的地址!
因为程序中的名称都是给程序员看的,而JVM操作的都是“地址”!