局部变量表

局部变量表是方法运行时的变量表,存在于.class文件中,由slot组成,可存放boolean至reference类型的数据。long和double占两个slot,由于数据模型原因,double为64位。slot可复用,当变量离开作用域,其他变量可复用该slot,通过编译器优化和垃圾回收机制实现内存管理。
摘要由CSDN通过智能技术生成

局部变量表我在之前提过,实际上就是方法运行时的变量表,已经在.class文件中存在了,但是我们还需要扣一下细节,Java虚拟机并没有规定变量的大小

只是说一个slot(数据的最小单位),必须可以存放一个boolean,byte,char,short,int,float,reference(引用类型)

实际上就是指一个slot至少可以存放一个32位的数据,即,4字节,对于引用类型来说可能不一定小于等于32位

因为虚拟机实现不同,如果引用类型所包含的信息足够大,是有可能超过32位的,如,锁的信息,对象的年龄代信息,对象所指向的内存信息等等

但是基本上目前的虚拟机经过一系列的优化,基本都可以控制在4字节之内完成全部信息的存储,所以这篇文章默认引用类型的长度小于等于4字节

至少可以,说明是大于等于,如果有哪个jvm设置slot为64位,也是可行的(实际上没人这样干,毫无意义的浪费内存)

而除去上面的这几种类型,还有两种没有提到,即,long和double,Java虚拟机将他们规定为64位的数据,

但是这里有一个问题,long是64位的很好理解,但是为什么double也是64位呢?

从范围来看,明显double已经超过64位可以容纳的最大长度相当多,我翻了很多网上的博客和论坛

网上的博客和论坛大部分是说是因为double采用了特殊的数据存储,但是大多讲的不好,我在这里用自己的话说一下吧

查看Java Double(即,double包装类)源码,可知0x1.fffffffffffffP+1023是double的最大长度,那么为什么是这个值呢?

将他转换为二进制

可以把1.fffffffffffff看做二进制的1(请忽略那个点)—1111(即二进制对于16进制的f)—1111*12(f太多了,省略)

也就是说前面的1.fffffffffffff实际上在二进制中占4*13+1位,共53位,而1023转换为二进制数,即为11–1111—1111

即,10位数,加上前面的53位,共63位,补上一位符号位,即为64位,这就是为什么double是64位的原因,在Java中double实际上是将两个数据存放在double中了

这是double的数据模型

位置 意义
1 符号位
2-54 精确数值
55-64 科学计数位

也就是说在doble中可靠数据最大只有17976931348623157即,2的53次方-1,同为浮点类型的float同理

而在jvm中通常把上文这两种64位的数据存放在两个slot中

也就是说,如果我们需要修改double中的数据,实际上需要操作两个slot,Java虚拟机明确规定了,如果字节码只操作其中一个slot,抛出异常

为了节省内存,slot是可以复用的,对于局部变量来说,如果一个变量离开了他的作用域范围,其他变量就可以复用这个slot

示例代码

public class Test {
   
    public static void main(String[] args)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值