您的位置:首页 > 其它

常量池技术

2015-07-07 14:15 302 查看


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实现了常量池技术,Float,Double 没有实现常量池技术

· Integer i1 = 40;

· Integer i2 = 40;

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

· Double d1=1.0;

· Double d2=1.0;

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

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

· Integer i4 = new Integer(40);

· Integer i5 = new Integer(40);

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

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

对于i1==i2+i3、i4==i5+i6结果为True,是因为,Java的数学计算是在内存栈里操作的,Java会对i5、i6进行拆箱操作,其实比较的是基本类型(40=40+0),他们的值相同,因此结果为True。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: