Java的String相关研究

使用工具:

vscode,编写java代码。
jvisualvm,分析虚拟机的内存,查看虚拟机内每一个类的实例数。

预备知识:

java虚拟机jvm启动时会申请一块内存,并将内存分为方法区,堆,虚拟机栈等。

  • 方法区存放类信息,常量,静态变量等数据。
  • 堆存放对象实例。
  • 虚拟机栈的每一个栈帧用于存放局部变量表,操作数,动态链接,方法出口等信息,程序执行进入代码块或者方法时会将此栈帧入栈,而当此代码块、方法运行完毕束后会出栈。

String的对象分布在方法区的运行时常量池内的字符串常量池与堆中,而在jdk1.7之后字符串常量池被移动到了Java堆中(与运行时常量池分离)。

研究问题:

String直接赋值与new String时都发生了什么

1)直接赋值时,会先查找字符串常量池里是否存在此字符串,若存在,则将此引用直接指向字符串常量池中已经存在的字符串。若没有存在,则会在字符串常量池里新建一个此字符串,并将此引用指向该字符串。
下面用代码以及内存分析证明一下:
在这里插入图片描述
程序运行到第6行时暂停,这时在jvisualvm里生成dump文件(文件里面有程序当前的堆内存内的全部数据),我们可以根据字符串对象的值查询此时的内存里有多少个值为"abc"的对象。
在这里插入图片描述
显然,整个内存里只有1个值为abc的字符串。

2)使用new String时,第一步类似于直接赋值,先检查字符串常量池中是否有与此字符串相同的字符串,若无则在字符串常量池中创建,若有则不做操作。之后会在堆内创建一个内容与该字符串相同的String对象。也就是会在内存里产生1~2个字符串对象。
下面用代码证明一下:
这段代码里用new String新建了一个值为abc的String对象,将会在字符串常量池与堆内分别建立一个值为abc的String对象。
在这里插入图片描述
在这里插入图片描述显然,内存里有2个值为abc的字符串。

下面看这段代码,
在这里插入图片描述
结合之前的测试,不难推测出,运行到第六行时内存中仍会有两个值为abc的字符串
首先在第四行,会在字符串常量池与堆内存中分别建立一个值为abc的字符串。
而第5行则会将a指向字符串常量池中的abc;
接下来用jvisualvm验证一下。
在这里插入图片描述
显然,与上一个代码运行时同样只有两个abc;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值