JVM内存区域(下)

常量池(方法区)

class常量池(静态常量池)

在class文件中除了有类的版本、字段、方法和接口等描述信息外。还有一项为常量池(Constant Pool Table),用于存放编译期间生成的各种字面量和符号引用。
在这里插入图片描述
字面量:给基本类型变量赋值的方式就叫做字面量或者字面值
比如:string a = “b”,这里的b就是字符串字面量,同样还有整数数据字面值、浮点类型字面量、字符字面量

符号引用:符号引用可以一组符号描述所引用的目标。符号引用可以是任何形式的字面量,java在编译的时候给每个java类都会编译成一个class文件,但是编译的时候虚拟机并不知道所引用类的内存地址,所以用符号引用来代替,而在类的解析阶段就是把符号引用转换为真正的内存地址的阶段。

运行时常量池

运行时常量池(runtime constant pool)是每一个类或者接口的常量池的运行时表示形式,他包括了若干个不同的常量,从编译器所知的数值字面量到必须运行期必须解析后才能或得的方法或者字段引用。存放符号引用和实际地址关系的常量池。

字符串常量池

String对象是对char数组进行封装实现的对象,主要有俩个成员变量,char数组、hash值。
在这里插入图片描述

string字符串

String对象是不可变性
了解string对象的实现后,string类被final关键字修饰了,而且变量char数组也被final修饰了。我们知道类被final修饰代表该类不可以继承,而char[]被final+private修饰,代表string对象不可被更改。Java实现的这个特性叫做string对象的不可变性,即string对象一旦创建成功,就不能再对他进行改变。
Java这样处理的好处在哪里?
第一:保证string对象的安全性,假设string对象是可变的,那么string对象可能被恶意修改
第二:保证hash属性值不会别频繁更新,确保了唯一性。使得类似hashmap容器才能实现相应的key-value缓存功能
第三:可以实现字符串常量池。在java中,通常有俩种创建字符串对象的方式,一种是通过字符串常量的方式来创建,如string str = “abc”;另一种是通过字符串变量new形式创建,如string str = new string(“abc”);

创建方式

1、 string str = “abc”;
当代码中使用这种方式创建字符串对象时,JVM首先会检查该对象是否存在字符串常量池中,如果在,就返回该对象引用;否则新的字符串将在常量池中被创建,这种方式可以减少一个值的字符串对象的重复创建,节约内存。(str只是一个引用)
在这里插入图片描述
2、 string str = new string(“abc”)
首先在编译类文件时,“abc”常量字符串将会被放入到常量结构中,在类加载中,“abc”将会在常量池中创建;其次,在调用new时,JVM命令将会调用string的构造函数,同时引用常量池中的“abc”字符串,在堆内存中创建一个string对象;最后,str将引用string对象

在这里插入图片描述
3、 使用new对象会创建在堆中,同时赋值的话,会在常量池中创建一个字符串对象赋值到堆中。具体的复制过程是先将常量池中的字符串压入栈中,在使用string的构造方法是,会拿到栈中的字符串作为构造方法的参数。这个构造函数是一个char数组的赋值过程,而不是new出来的,所以是引用了常量池中的字符串对象,存在引用关系。
在这里插入图片描述
4、 string str2 = “ab”+“cd”+“ef”;
编程过程中,字符串的拼接很常见,前面讲过string对象是不可变的,如果我们使用string对象相加,拼接我们想要的字符串,是不是就会产生多个对象呢?例如以下代码:
分析代码可知:首先会生成ab对象,再生成abcd对象,最后生成abcdef对象,理论上这段代码是最低效的
编译器会自动优化这段代码,编译后的代码,自动优化为string str = “abcdef”;
5、 intern
string的intern方法,如果常量池中有相同值,就会重复使用该对象,返回对象引用。
在这里插入图片描述
总结:
1、 new string()会在堆内存中创建一个a的string对象,值将会在常量池中创建
2、 在调用intern()方法之后,回去常量池中查找是否存在等于该字符串对象的引用,有就返回引用。
3、 调用new string()会在堆内存中创建一个b的string对象
4、 在调用intern方法之后,会去常量池中查找是否有等于该字符串对象的引用,有就返回引用,所以a和b引用的是同一个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值