【jvm】字符串常量池问题
目录
- 一、基本概念
- 1.1 说明
- 1.2 特点
- 二、存放位置
- 2.1 JDK1.6及以前
- 2.2 JDK1.7
- 2.3 JDK1.8及以后
- 三、工作原理
- 3.1 创建字符串常量
- 3.2 使用new关键字创建字符串
- 四、intern()方法
- 4.1 作用
- 五、优点
- 六、字节码分析
- 6.1 示例1
- 6.1.1 代码示例
- 6.1.2 字节码
- 6.1.3 解析
- 6.2 示例2
- 6.2.1 代码示例
- 6.2.2 分析(jdk8)
- 6.3 示例3
- 6.3.1 代码示例
- 6.2.2 分析(jdk8)
一、基本概念
1.1 说明
- 1.JVM字符串常量池是Java虚拟机(JVM)中一个特殊的内存区域。
- 2.JVM字符串常量池用于存储字符串常量。
- 3.提高性能和减少内存开销。
- 4.字符串常量池是JVM用于存储字符串常量的一个内存区域,避免了相同字符串的重复创建,节省内存空间。
1.2 特点
- 1.字符串常量池中的字符串对象是不可变的。
- 2.相同的字符串常量在池中只存储一份,通过引用共享。
二、存放位置
2.1 JDK1.6及以前
- 1.字符串常量池存放在永久代中,永久代是非堆内存的一部分,用于存储类的元数据、常量、静态变量等。
2.2 JDK1.7
- 1.字符串常量池从永久代移动到了Java堆中,而运行时常量池保留在永久代中。
- 2.这一变化为了适应永久代内存限制问题,并提升性能。
2.3 JDK1.8及以后
- 1.永久代被移除,取而代之的是元空间,字符串常量池仍然位于Java堆中。
- 2.运行时常量池被移动到元空间。
三、工作原理
3.1 创建字符串常量
- 1.使用双引号创建字符串时(String a = “123”; ),JVM会首先在字符串常量池中查找是否已存在该字符串。
- 2.如果存在,则直接返回池中该字符串的引用。
- 3.如果不存在,则在常量池中创建该字符串的实例,并返回其引用。
3.2 使用new关键字创建字符串
- 1.使用new关键字创建字符串对象(如String str = new String(“abc”);)时,JVM会在堆内存中创建一个新的字符串对象,而不管字符串常量池中是否已存在相同的字符串。
- 2.如果需要,可以通过调用intern()方法将新创建的字符串对象放入常量池中。
四、intern()方法
4.1 作用
- 1.intern()方法是String类的一个本地方法。
- 2.用于将字符串对象添加到字符串常量池中。
- 3.如果常量池中已经包含了一个等于此String对象的字符串(使用equals(Object)方法确定),则返回代表池中这个字符串的String对象的引用。
- 4.否则,将此String对象包含的字符串添加到常量池中,并返回此String对象的引用。
五、优点
- 1.节省内存:通过共享相同的字符串常量,避免了不必要的重复创建。
- 2.提高性能:减少了对象创建和垃圾回收的开销。
- 3.简化字符串比较:由于字符串常量池中的字符串是唯一的,可以使用==操作符来比较字符串的引用,从而简化比较操作。
六、字节码分析
6.1 示例1
6.1.1 代码示例
@Test
public void test(){String str1 = new String("hello") + new String("world");String str2 = "helloworld";System.out.println(str1 == str2);
}
6.1.2 字节码
0 new #2 <java/lang/StringBuilder>3 dup4 invokespecial #3 <java/lang/StringBuilder.<init> : ()V>7 new #4 <java/lang/String>
10 dup
11 ldc #5 <hello>
13 invokespecial #6 <java/lang/String.<init> : (Ljava/lang/String;)V>
16 invokevirtual #7 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
19 new #4 <java/lang/String>
22 dup
23 ldc #8 <world>
25 invokespecial #6 <java/lang/String.<init> : (Ljava/lang/String;)V>
28 invokevirtual #7 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
31 invokevirtual #9 <java/lang/StringBuilder.toString : ()Ljava/lang/String;>
34 astore_1
35 ldc #10 <helloworld>
37 astore_2
38 getstatic #11 <java/lang/System.out : Ljava/io/PrintStream;>
41 aload_1
42 aload_2
43 if_acmpne 50 (+7)
46 iconst_1
47 goto 51 (+4)
50 iconst_0
51 invokevirtual #12 <java/io/PrintStream.println : (Z)V>
54 return
6.1.3 解析
- 1. 0 new #2 <java/lang/StringBuilder>: 调用StringBuilder的new方法
- 2. 3 dup:复制操作数栈栈顶的一个字(通常是对象引用或数据类型值),并将这个字重新压入栈顶。
- 3. 4 invokespecial #3 <java/lang/StringBuilder. : ()V>:执行StringBuilder的初始化方法,会消耗操作数栈顶一个字。
- 4. 7 new #4 <java/lang/String>:new一个String对象,对象的引用压入操作数栈。
- 5. 10 dup:复制操作数栈栈顶的一个字(通常是对象引用或数据类型值),并将这个字重新压入栈顶。
- 6. 11 ldc #5 :加载栈顶的一个字,即hello。
- 7. 13 invokespecial #6 <java/lang/String. : (Ljava/lang/String;)V>:初始化String,消耗一个string对象的引用和复制的字。
- 8. 16 invokevirtual #7 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;> : append操作,将hello追加进来。
- 9. 19 new #4 <java/lang/String> : new一个String对象,对象的引用压入操作数栈。
- 10. 22 dup:复制操作数栈栈顶的一个字(通常是对象引用或数据类型值),并将这个字重新压入栈顶。
- 11. 23 ldc #8 : 加载栈顶的一个字,即world。
- 12. 25 invokespecial #6 <java/lang/String. : (Ljava/lang/String;)V>:初始化String,消耗一个string对象的引用和复制的字。
- 13. 28 invokevirtual #7 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>: append操作,将world追加进来。
- 14. 31 invokevirtual #9 <java/lang/StringBuilder.toString : ()Ljava/lang/String;> :调用StringBuilder的toString方法
- 15. StringBuilder的toString方法中是直接new了一个String对象。
- 16. 而String str2 = “helloworld”;是常量池的引用。
- 17. 因此不是同一个内存地址,所以结果是false。
6.2 示例2
6.2.1 代码示例
@Testpublic void test(){String str1 = new String("hello") + new String("world");str1.intern();String str2 = "helloworld";System.out.println(str1 == str2);}
6.2.2 分析(jdk8)
- 1.str1是直接new了一个对象,执行intern()方法后,将字符串对象添加到字符串常量池中。
- 2.String str2 = “helloworld”;会先在字符串常量池中找是否有,如果有则返回其对象的引用。
- 3.所以结果是true。
6.3 示例3
6.3.1 代码示例
@Testpublic void test(){String str1 = new String("helloworld") ;String str2 = "helloworld";String intern = str1.intern();System.out.println(str1 == str2);System.out.println(str1 == intern);System.out.println(str2 == intern);}
6.2.2 分析(jdk8)
- 1.str1在堆上new了一个string对象。
- 2.str2是将字面量“helloworld”放入字符串常量池中。
- 3.str1调用intern方法,判断字符串常量池中有没有helloworld,发现有,返回了该字符串常量池的引用即str2。
- 4.此时str1不等于str2。str2和intern是相等的。
相关文章:
【jvm】字符串常量池问题
目录 一、基本概念1.1 说明1.2 特点 二、存放位置2.1 JDK1.6及以前2.2 JDK1.72.3 JDK1.8及以后 三、工作原理3.1 创建字符串常量3.2 使用new关键字创建字符串 四、intern()方法4.1 作用 五、优点六、字节码分析6.1 示例16.1.1 代码示例6.1.2 字节码6.1.3 解析 6.2 示例26.2.1 代…...
STM32学习和实践笔记(39):I2C EEPROM实验
1.I2C总线介绍 I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备,是微电子通信控制领域广泛采用的一种总线标准。 它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。I…...
【Js】导出 HTML 为 Word 文档
在 Web 开发中,有时我们希望用户能够将网页上的 HTML 内容保存为 Word 文档,以便更方便地分享和打印。 html样式 word文档 工具准备 1、 html-docx-js - npm html-docx-js是一个 JavaScript 库,用于将 HTML 内容转换为 Word 文档的格式。它…...
c++入门基础篇(上)
目录 前言: 1.c++的第一个程序 2.命名空间 2.1 namespace的定义 2.2 命名空间使用 3.c++输入&输出 4.缺省参数 5.函数重载 前言: 我们在之前学完了c语言的大部分语法知识,是不是意…...
Java实现数据结构——双链表
目录 一、前言 二、实现 2.1 类的创建 三、对链表操作实现 3.1 打印链表 3.2 插入数据 3.2.1 申请新节点 3.2.2 头插 编辑 3.2.3 尾插 3.2.4 链表长度 3.2.5 任意位置插入 3.3 删除数据 3.3.1 头删 3.3.2 尾删 3.3.3 删除指定位置数据 3.3.4 删除指定数据 3…...
Python应用爬虫下载QQ音乐歌曲!
目录: 1.简介怎样实现下载QQ音乐的过程; 2.代码 1.下载QQ音乐的过程 首先我们先来到QQ音乐的官网: https://y.qq.com/,在搜索栏上输入一首歌曲的名称; 如我在上输入最美的期待,按回车来到这个画面 我们首…...
AWS-WAF-Log S3存放,通过Athena查看
1.创建好waf-cdn 并且设置好规则和log存储方式为s3 2. Amazon Athena 服务 使用 (注意s3桶位置相同得区域) https://docs.aws.amazon.com/zh_cn/athena/latest/ug/waf-logs.html#waf-example-count-matched-ip-addresses 官方文档参考,建一个分区查询表…...
无法解析主机:mirrorlist.centos.org Centos 7
从 2024 年 7 月 1 日起,在 CentOS 7 上,请切换到 Vault 存档存储库: vi /etc/yum.repos.d/CentOS-Base.repo 复制/粘贴以下内容并注意您的操作系统版本。如果需要,请更改。此配置中的版本为 7.9.2009: [base] name…...
自动驾驶论文总结
1.预测 1.1光栅化 代表性论文 Motion Prediction of Traffic Actors for Autonomous Driving using Deep Convolutional Networks (Uber)MultiPath (Waymo) 问题 渲染信息丢失感受野有限高计算复杂度 1.2图神经网络 1.2.1 图卷积 LaneGCN (uber 2020) 1.2.2 边卷积 V…...
【uniapp微信小程序】uniapp微信小程序——页面通信
uniapp微信小程序——页面通信 在开发微信小程序过程中,页面之间的通信是一个常见需求。在使用 uniapp 开发微信小程序时,我们可以采用多种方式实现页面之间的数据传递和状态共享。本文将详细介绍几种常见的实现方式,以供开发者参考。 1. 页…...
【笔记】从零开始做一个精灵龙女-画贴图阶段(上)
此文只是我的笔记,不包全看懂,有问题可评论 PS贴图加工 1.打开ps 拖入uv图,新建图层,设置背景色为灰色,改一下图层名字 2.按z缩小一下uv图层,拖入实体uv图片(目的是更好上色,比如…...
线性代数|机器学习-P22逐步最小化一个函数
文章目录 1. 概述2. 泰勒公式3. 雅可比矩阵4. 经典牛顿法4.1 经典牛顿法理论4.2 牛顿迭代法解求方程根4.3 牛顿迭代法解求方程根 Python 5. 梯度下降和经典牛顿法5.1 线搜索方法5.2 经典牛顿法 6. 凸优化问题6.1 约束问题6.1 凸集组合 Mit麻省理工教授视频如下:逐步…...
SpringCloudAlibaba Nacos配置中心与服务发现
目录 1.配置 1.1配置的特点 只读 伴随应用的整个生命周期 多种加载方式 配置需要治理 1.2配置中心 2.Nacos简介 2.1特性 服务发现与服务健康检查 动态配置管理 动态DNS服务 服务和元数据管理 3.服务发现 1.配置 应用程序在启动和运行的时候往往需要读取一些配置信…...
.NET 一款获取内网共享机器的工具
01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失…...
备考美国数学竞赛AMC8和AMC10:吃透1850道真题和知识点(持续)
距离接下来的AMC8、AMC10美国数学竞赛还有几个月的时间,实践证明,做真题,吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一。 通过做真题,可以帮助孩子找到真实竞赛的感觉,而且更加贴近比赛的内容,…...
旅游景区度假村展示型网站如何建设渠道品牌
景区、度假村、境外旅游几乎每天的人流量都非常高,还包括本地附近游等,对景区及度假村等固定高流量场所,品牌和客户赋能都是需要完善的,尤其是信息展示方面,旅游客户了解前往及查看信息等。 通过雨科平台建设景区度假…...
Python酷库之旅-第三方库Pandas(021)
目录 一、用法精讲 52、pandas.from_dummies函数 52-1、语法 52-2、参数 52-3、功能 52-4、返回值 52-5、说明 52-6、用法 52-6-1、数据准备 52-6-2、代码示例 52-6-3、结果输出 53、pandas.factorize函数 53-1、语法 53-2、参数 53-3、功能 53-4、返回值 53-…...
jvm 06 补充 OOM 和具体工具使用
1.OOM 是什么 OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”,来源于java.lang.OutOfMemoryError。看下关于的官方说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memor…...
使用机器学习 最近邻算法(Nearest Neighbors)进行点云分析 (scikit-learn Open3D numpy)
使用 NearestNeighbors 进行点云分析 在数据分析和机器学习领域,最近邻算法(Nearest Neighbors)是一种常用的非参数方法。它广泛应用于分类、回归和聚类分析等任务。下面将介绍如何使用 scikit-learn 库中的 NearestNeighbors 类来进行点云数…...
安装jenkins最新版本初始化配置及使用JDK1.8构建项目详细讲解
导读 1.安装1.1.相关网址1.2.准备环境1.3.下载安装 2. 配置jenkins2.1.安装插件2.2.配置全局工具2.3.系统配置 3. 使用3.1.配置job3.2.构建 提示:如果只想看如何使用jdk1.8构建项目,直接看3.1即可。 1.安装 1.1.相关网址 Jenkins官网:https…...
一站式图像生成与编辑:Nano Banana 图像生成与编辑 API(包含多个示例和实用技巧)
在电商、时尚内容、网红营销或产品视觉设计领域,你是否曾面临以下挑战? 如何快速为同一肖像尝试多套服装?如何快速生成相同产品在不同场景/风格下的图像?如何将多个来源的材料合成一张“看起来真实”的图像? Ace Dat…...
Vue3 + Element Plus项目实战:如何封装一个带比例锁定和实时预览的智能图片裁剪上传组件?
Vue3 Element Plus实战:构建智能图片裁剪上传组件的工程化实践 在当今的Web应用中,图片上传几乎是每个系统的标配功能。但简单的文件选择器往往无法满足专业需求——设计师需要精确控制图片比例,产品经理要求实时预览效果,而开发…...
OpenClaw备份策略:Qwen3-32B配置与技能库容灾方案
OpenClaw备份策略:Qwen3-32B配置与技能库容灾方案 1. 为什么需要备份OpenClaw环境 去年冬天的一个深夜,我的OpenClaw自动化脚本突然停止工作。经过排查发现是SSD故障导致~/.openclaw目录损坏,丢失了精心调校的模型配置、技能库和任务历史记…...
客户和采购都在用豆包、deepseek查资料,怎么才能让这些国内头部大模型在回答时优先推荐公司的产品?
随着人工智能技术的爆发,企业获客与消费者决策的路径正在发生深刻的重构。据近期的公开市场调研与行业报告显示,包括豆包、DeepSeek、文心一言在内的国内头部大模型,其月活跃用户数正呈现指数级增长。一个不可忽视的趋势是:无论是…...
javascript之Dom查询操作1
1.通过Id获取单个元素假定要获取下面html代码里面id是div1的div标签内容语法是document.getElementById(Id值)<div id"div1">div1</div>let a document.getElementById("div1") console.log(a)2.根据name属性值获取语法是document.getElement…...
好写作AI“文献综述智囊团”:开启学术探索新航道
在学术研究的广袤天地中,文献综述宛如一座灯塔,为研究者照亮前行的道路,它不仅是对前人研究成果的全面梳理与总结,更是为后续研究搭建起坚实的理论基石。然而,撰写一份高质量的文献综述并非易事,海量文献的…...
如何从视频中高效提取幻灯片:智能工具应用指南
如何从视频中高效提取幻灯片:智能工具应用指南 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 你是否曾遇到这样的困扰:参加线上会议后想整理演示文稿&#x…...
Three.js实战:打造交互式3D中国地图可视化
1. 从零开始搭建3D中国地图 第一次接触Three.js时,我被它强大的3D渲染能力震撼到了。作为一个长期从事数据可视化的开发者,我一直在寻找能够将地理数据以更生动方式呈现的工具。Three.js配合D3.js的组合,完美解决了这个问题。 1.1 数据准备与…...
实测nanobot:5分钟搭建个人AI助手,还能轻松接入QQ聊天
实测nanobot:5分钟搭建个人AI助手,还能轻松接入QQ聊天 1. nanobot核心优势解析 nanobot作为一款超轻量级个人AI助手解决方案,在技术架构和用户体验上都有显著突破。这个受OpenClaw启发的项目,仅用约4000行代码就实现了完整的智能…...
【从零开始学Java | 第二十五篇】TreeSet
目录 前言 一、TreeSet的特点 二、TreeSet集合默认的规则 1.默认排序/自然排序 2.比较器排序 总结 前言 在 Java 的集合框架中,Set 接口代表了一个不允许存在重复元素的集合。我们最常用的通常是 HashSet,因为它提供了极高的查找和插入效率。但是&…...
