常量池技术

 

 

2.1 程序计数器寄存器(The pc Register)

2.2 栈

JVM为每个新创建的线程都分配一个栈.也就是说,对于一个Java程序来说,它的运行就是通过对栈的操作来完成的。它用来保存局部变量的值,包括:1.用来保存基本数据类型的值;2.保存类的实例,即堆区对象的引用(指针)。3.用来保存加载方法时的帧,当嵌套方法调用时,嵌套越深,stack的内存就越晚才能释放,因此,在实际开发过程中,不推荐大家使用递归来进行方法的调用,递归很容易导致stack flow。

2.3 堆

每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。

2.4 堆和栈的区别

2.5 方法区

JVM有一个被所有线程共享的方法区。方法区类似于传统语言的编译后代码的存储区,或者UNIX进程中的text段。它存储每个类结构例如常量池(constant pool),成员字段域和方法和构造函数,包含类和实例初始化和接口类型类型中用到的特殊方法的代码。

方法区在虚拟机启动时创建。尽管方法区在逻辑上是heap的一部分,简单的实现仍然可以选择对它既不回收也不压缩。

 

 

Byte  Character Boolean Short Integer Long实现了常量池技术,FloatDouble 没有实现常量池技术

 

·          Integer i1 = 40;  

·          Integer i2 = 40;

因为Integer实现了常量池技术,所以在池中i1i2指向同一个地址,故 i1 == i2 true

 

·          Double d1=1.0;  

·          Double d2=1.0; 

因为Double 没有实现常量池技术,所以Doubled1=1.0;相当于Double d1=new Double(1.0);

d2类同,各自new了一个对象,所以d1d2存放的指针不同,指向的对象不同,所以不相等

 

·  Integer i4 = new Integer(40);  

·  Integer i5 = new Integer(40); 

虽然Integer实现了常量池技术,但是他们各自new了一个对象。i4i5 均是引用类型,在栈中存储指针,因为Integer是包装类。但是由于他们各自都是new出来的,因此不再从常量池寻找数据,而是从堆中各自new一个对象,然后各自保存指向对象的指针,所以i4i5不相等,因为他们所存指针不同,所指向对象不同,故i4==i5为false。

 

但是需要注意的是:以上提到的几种基本类型包装类均实现了常量池技术,但他们维护的常量仅仅是【-128127】这个范围内的常量,如果常量值超过这个范围,就会从堆中创建对象,不再从常量池中取。比如,把上边例子改成Integer i1 = 400; Integer i2 = 400;,很明显超过了127,无法从常量池获取常量,就要从堆中new新的Integer对象,这时i1i2就不相等了。

 

对于i1==i2+i3i4==i5+i6结果为True,是因为,Java的数学计算是在内存栈里操作的,Java会对i5i6进行拆箱操作,其实比较的是基本类型(40=40+0),他们的值相同,因此结果为True

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值