JVM(HotSpot):字符串常量池(StringTable)

文章目录

  • 一、内存结构图
  • 二、案例讲解
  • 三、总结

一、内存结构图

JDK1.6
在这里插入图片描述
JDK1.8
在这里插入图片描述
我们发现,StringTable移入了Heap里面。所以,应该想到,StringTable将受到GC管理。
其实,1.6中,在方法区中的时候,也是受GC管理的。

二、案例讲解

题目

public class Demo7 {public static void main(String[] args) {String s1 = "a";String s2 = "b";String s3="a" + "b";String s4 = s1 + s2;String s5 = "ab";String s6 = s4.intern();//问提System.out.println(s3 == s4);System.out.println(s3 == s5);System.out.println(s3 == s6);String x2 = new String("c") + new String("d");String x1 = "cd";x2.intern();//问,如果调换了最后两行代码,如果是1.6,?System.out.println(x1 == x2);}
}

首先,我们要知道,== 号进行的比较,是比较引用的内存地址是否相同。
如果想要比较String的内容,用equals方法就可以。

字节码
在这里插入图片描述
主要看下红线处的几行代码

简单理解就是:
1、StringTable是一个HashTable结构(桶(数组)+链表
2、代码翻译

String s1 = "a";
String s2 = "b";
String s3="a" + "b";
String s4 = s1 + s2;

前三行代码可以简单的理解为,JVM启动后,会创建一个StringTable
我现在简单点把StringTable表示成StringTable[]这样
于是
上面三行代码就是
StringTable [ "a", "b" ,"ab" ]
最后一行代码是
new StringBuilder().append("a").append("b").toString() new String("ab")

intern方法
就是将字符串主动放入StringTable中,并返回StringTable中的引用地址。

1.8和1.6的区别就是
1.8不在复制对象。所以,原来的引用指向会发生改变。
而1.6是复制对象,所以,原来的引用指向不会发生变化。

三、总结

常量池中的字符串仅仅是一个符号,第一次用到时,才会变成对象。
利用串池的机制,来避免重复创建字符串对象。
字符串变量凭借的原理是StringBuilder(1.8)
字符串常量凭借的原理是编译期优化
可以用intern方法,主动将串池中没有的字符串对象放入串池中。

  • 1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串
    池中的对象引用返回
  • 1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,
    放入串池, 会把串池中的对象引用返回

简单记忆
字符串的创建方式,如果是new的方式,就是放入堆中,而不放入串池中。
如果是""双引号方式创建,则是直接放入串池中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从底层理解为什么常量区中的代码不能被修改?

目录 前言:一、了解虚拟地址二、页表映射三、常量区不能被修改的原理四、常量区不可修改的意义 前言: 平时我们在编写代码时都会用到或遇到所谓的常量区或者不可修改的代码,比如说用双引号包起来字符串(“Hello World”&#xff…

微服务SpringSession解析部署使用全流程

目录 1、SpringSession简介 2、实现session共享的三种方式 1、修改Tomcat配置文件 2、Nginx负载均衡策略 3、redis统一存储 0、准备工作 1、本地服务添加依赖 2、修改本地服务配置文件 3、添加application.properties文件 4、添加nacos - redis配置 5、修改本地项目…

Linux启动mysql报错

甲方公司意外停电,所有服务器重启后,发现部署在Linux上的mysql数据库启动失败.再加上老员工离职,新接手项目,对Linux系统了解不多,解决起来用时较多,特此记录。 1.启动及报错 1.1 启动语句1 启动语句1&a…

全站最详细的Python环境配置步骤

1、官网下载IDE JetBrains下载 2、IDE下载、安装步骤 这里展示的是如何在Windows上下载、安装Pycharm工具,Linux的步骤类似。 2.1、选择开发者工具 选择开发者工具 2.2、选择Pycharm 选择Pycharm 2.3、选择下载 选择下载 2.4、选择社区版 一般而言&#xff…

基于SpringBoot+Vue的留守儿童爱心网站系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

MyBatis的注入问题

对之前文章的补充:MyBatis中的#{}与${}注入问题----原文链接 前言: MyBatis是一个流行的Java持久层框架,用于将对象与数据库中的数据进行映射。然而,如果不当使用,MyBatis也可能受到诸如SQL注入这类的安全问题的影响。…

解决VRM格式模型在Unity中运行出现头发乱飞等问题

1、问题 通过VRoidStudio制作导出的vrm格式的模型,放在unity中使用时,一运行就会出现头发乱飞,没有自然下垂的问题 2、解决方法 将模型下的secondary中的所有VRM Spring Bone脚本中的Drag Force改为1,Hit Radius改为0 修改后…

JAVA笔记 | 实际上用到的策略模式(可直接套用)

自己开发中用到了策略模式,这样写不一定是最好的,但是满足了业务场景跟使用要求,做个笔记,下次有用到可以快速复习跟套用 假设使用场景:有几只宠物,猫跟狗等,要求他们做各种动作,比如…

828华为云征文 | 华为云Flexus云服务器X实例搭建Zabbix网络设备监视系统(Ubuntu服务器运维)

前言 Flexus X实例内嵌智能应用调优算法,性能强悍,基础模式GeekBench单核及多核跑分可达同规格独享型实例的1.6倍,性能模式更是超越多系列旗舰型云主机,为企业业务提供强劲动力。 💼 Flexus X Zabbix:打造…

PWM驱动LED呼吸灯

背景知识:TIM输出比较-CSDN博客 stm32f10x_tim.h函数 // *** OC是Output Compare输出比较函数 void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); void TI…

苹果盛宴:iPhone 16系列领衔,智能穿戴新潮流来袭

在科技界备受瞩目的苹果秋季发布会上,众多新品悉数亮相,从全新的Apple Watch系列到AirPods系列,再到备受期待的iPhone 16系列,每一款产品都以其独特的创新和卓越的性能,再次定义了智能设备的高标准。 本文将带您领略这…

实验5 预备实验2-配置单个的路由器

配置单个的路由器 一、实验目的 此次试验目的是了解思科网络设备的配置基本特点及IOS命令基本操作方法。这些是配置思科设备的重要前提。 二、实验内容及结果 1、实验环境搭建 添加一个模块化的路由器,单击Packet Tracer 5.3的工作区中刚添加的路由器,…

Go实现RabbitMQ消息模式

【目标】 go实现RabbitMQ简单模式和work工作模式 go实现RabbitMQ 消息持久化和手动应答 go实现RabbitMQ 发布订阅模式 go使用MQ实现评论后排行榜更新 1. go实现简单模式 编写路由实现生产消息 实现生产消息 MQ消息执行为命令行执行,所以创建命令行执行函数mai…

【React】react项目中的redux使用

1. store目录结构设计 2. react组件中使用store中的数据——useSelector 3. react组件中修改store中的数据——useDispatch 4. 示例 react-basic\src\store\moduels\counterStore.js import { createSlice } from reduxjs/toolkitconst counterStore createSlice({name: cou…

Flutter屏幕适配

我们可以根据下面有适配属性的Widget来进行屏幕适配 1.MediaQuery 通过它可以直接获得屏幕的大小(宽度 / 高度)和方向(纵向 / 横向) Size screenSize MediaQuery.of(context).size; double width screenSize.width; double h…

【Linux:线程概念】

目录 概念: 创建线程的函数:​编辑 ​编辑 有多进程为什么还需要有多线程? 线程调度的成本为什么低? 进程与线程的区别: 概念: 线程是CPU的基本调度单位,在进程内部运行。在内核中&#xff…

CSS 效果:实现动态展示双箭头

最近写了一段 CSS 样式,虽然不难,但实现过程比较繁琐。这个效果结合了两个箭头,一个突出,一个内缩,非常适合用于步骤导航或选项卡切换等场景。样式不仅仅是静态的,还可以通过点击 click 或者 hover 事件&am…

Java的栈帧和动态链接是什么?

在 Java 的面试过程中,不可避免的一个面试题那就是 JVM,而 JVM 的面试题中,有各种,比如在堆中会被问到的关于垃圾回收机制的相关问题,在栈中会被问到入栈以及出栈的过程,来聊一下关于栈的相关问题&#xff…

C0008.Clion利用C++开发Qt界面,使用OpenCV时,配置OpenCV方法

安装OpenCV 配置环境 配置Clion中的CMakeLists.txt文件 # 设置OpenCV的安装路径 set(OpenCV_DIR "D:/OpenCv_Win/opencv/build/x64/vc16/lib"

分糖果C++

题目&#xff1a; 样例解释&#xff1a; 样例1解释 拿 k20 块糖放入篮子里。 篮子里现在糖果数 20≥n7&#xff0c;因此所有小朋友获得一块糖&#xff1b; 篮子里现在糖果数变成 13≥n7&#xff0c;因此所有小朋友获得一块糖&#xff1b; 篮子里现在糖果数变成 6<n7&#xf…