JVM字符串常量池StringTable
目录
一、StringTable为什么要调整
二、String的基本特性
三、String的内存分配
四、字符串拼接操作
五、intern()方法
六、Stringtable的垃圾回收
七、G1中String去重操作
一、StringTable为什么要调整
jdk7之前,hotspot对于方法区的实现是永久代,常量池包括字符串常量池放于永久代中;
jdk7时,hotspot将字符串常量池(还有静态变量)放在了堆中。有一点“去永久代”的苗头
jdk8之后,hotspot取出永久代,取而代之的是使用本地内存的元空间。字符串常量池还是在堆中。
为什么要将字符串常量池StringTable放在堆中?
jdk7中将StringTable放到了堆空间中,因为永久代的回收效率很低。在fullGC的时候才触发,而fullGC是老年代空间不足,永久代不足时才触发,触发次数较少,甚至在开发中我们要避免出现fullGC。这就导致了StringTable回收效率不高,而我们开发中会创建大量的字符串,回收效率低,导致永久代内存不足。放到堆里,能及时回收内存。
二、String的基本特性
jdk8及以前,内部定义了final char[] value用于存储字符串数据
JDK9时改为byte[] + 字符类型标记,为什么做出这个改变呢?
char数组一个char占16bits(两个字节),String是堆空间的主要部分,大部分是latin-1字符,一个字节就够了,这样会有一半空间浪费。所以采用byte数组+字符串类型,如果是中文等UTF-16 的用两个字节存储。
StringBuffer,StringBuilder同样做了修改
String为什么不可变?
因为底层数组被final修饰。而且其类自身也被final修饰,这就导致了不能通过继承去修改其内部结构。保证了其不可变性。
- 当字符串重新赋值,需要重写指定内存区域赋值,不能使用原有的value进行赋值
- 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能对使用原有的value进行赋值
- 当调用String的replace方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
字符串常量池中不会存储相同的字符串的
String的String pool是一个固定大小的HashTable,默认大小长度是1009,如果放进String Pool的String非常多,就会造成Hash冲突严重,从而导致链表会很长,而链表长了,直接影响就是调用String.intern时性能会大幅下降
- -XX:StringTableSize可设置StringTable的大小
- JDK6固定1009,jdk7中StringTable默认的长度是60013,JDK8时默认是60013,1009是可设置的最小值
三、String的内存分配
Java语言中有8种基本数据类型和一种比较特殊的类型String,这些类型为了使他们再运行过程中速度更快,更节省内存,都提供了一种常量池的概念
String的常量池比较特殊,主要使用方法有两种
- 直接使用双引号,声明出来的String对象会直接存储在常量池中
- 如果不是双引号声明的String对象,可以使用String提供的intern()方法
jdk6及之前,字符串常量池存在永久代
jdk7中,字符串常量池调整到Java堆中,调优时仅需调整堆大小就可以
四、字符串拼接操作
常量与常量的拼接结果在常量池,原理是编译期优化

只要其中有一个变量,拼接结果就在堆中(常量池以外的堆),变量的拼接原理是StringBuilder

String res = s1 + s2;
// 实际上是StringBuilder s = new StringBuilder().append(s1).append(s2);
// 然后调用s.toString();

如果拼接的结果调用intern方法,则主动将常量池中还没有的字符串对象放入池中,并返回此对象地址
字符串拼接操作不一定使用的是StringBuilder如果拼接符号左右两边都是字符串常量或常量引用,则仍然使用编译期优化,即非StringBuilder的方式
针对final修饰类,方法,基本数据类型,引用数据类型变量的结构时,能使用final尽量使用上

五、intern()方法
jdk1.6中,将这个字符串对象放入串池
- 如果串池中有,则并不会放入,返回已有串池中的对象的地址,
- 如果没有,会把对象复制一份,放入串池,并返回串池中的对象地址
jdk1.7起,将这个字符串对象尝试放入串池
- 如果串池中有,则并不会放入,返回已有的串池中的对象的地址
- 如果没有,则会把对象的引用地址复制一份,放入串池,并返回串池中的引用地址
例子:

前置知识
newString("ab")会创建几个对象?
2个对象,查看字节码验证。一个是常量池ab,一个是new出来在堆空间。(前提是常量池没有ab)
new String("a")+new String("b")?
- 对象1,有拼接操作就newStringBuilder
- 对象2,new一个String
- 对象3,常量池a
- 对象4,new String
- 对象5,常量池b
- 对象6,StringBuilder,toString方法会new String返回
- 注意:toString方法这里new String并不会向字符串常量池中放入"ab",不像我们平时上面一样会放入一个“ab”在常量池中。
结果
jdk6 false false
jdk7/8 false true
分析:
jdk6的intern会复制一份"1"放入字符串常量池。但是new的时候其实已经放入常量池了,所以这里intern没啥用,此时s2拿到的就是常量池的那一份。而s是指向堆中new出来的String对象,所以为false
s3这里intern的时候常量池没有“11”,所以会复制一份放入常量池,此时s4拿到的就是常量池的那一份。而s3指向堆中new出来的String对象,所以为false
jdk7/8的intern是复制引用地址放入字符串常量池,但是new的时候其实已经放入常量池了,所以这里intern没啥用,此时s2拿到的就是常量池的那一份。所以为false
s3这里intern的时候常量池没有“11”,所以会复制引用放入常量池,此时s4拿到的就是常量池的那一份引用。而s3也指向堆中new出来的String对象,所以为true
六、Stringtable的垃圾回收
-XX:+PrintStringTableStatistics
七、G1中String去重操作
背景:对许多Java应用,做的测试结果如下
- 堆存货数据集合里面String对象占了25%
- 堆存活数据集合里面重复的String对象有13.5%
- String对象的平均长度是45
许多大规模的Java应用的瓶颈在于内存。Java堆中存活的数据集合差不多25%是String对象,这里差不多一半的String对象是重复的, 重复是指equals方法=true,堆上重复的String对象必然是一种内存的浪费。G1垃圾收集器中实现自动持续对重复的String对象进行去重,这样避免浪费。
相关文章:
JVM字符串常量池StringTable
目录 一、StringTable为什么要调整 二、String的基本特性 三、String的内存分配 四、字符串拼接操作 五、intern()方法 六、Stringtable的垃圾回收 七、G1中String去重操作 一、StringTable为什么要调整 jdk7之前,hotspot对于方法区的实现是永久代ÿ…...
【华为OD题库-010】寻找矿堆的最大价值-Java
题目 给你一个由0(空地)、1(银矿)、2(金矿)组成的的地图,矿堆只能由上下左右相邻的金矿或银矿连接形成。超出地图范围可以认为是空地。 假设银矿价值1,金矿价值2,请你找出地图中最大价值的矿堆并输出该矿堆的价值 输入描述 地图元素信息如: 2…...
在PyTorch中使用CUDA, pytorch与cuda不同版本对应安装指南,查看CUDA版本,安装对应版本pytorch
目录 1 查看本机CUDA版本 2 查看对应CUDA的对应pytorch版本安装 3 用pip 安装 4 用conda安装 5 验证安装 在PyTorch中使用CUDA,根据你的具体环境和需求调整版本号,确保安装的PyTorch版本与你的CUDA版本兼容。 在PyTorch中使用CUDA,你需…...
copilot 产生 python工具函数并生成单元测试
stock.py 这个文件,我只写了注释(的开头),大部分注释内容和函数都是copilot # split a string and extract the environment variable from it # input can be , pathabc, pathabc;pathdef, pathabc;pathdef;pathghi # output i…...
缓存与数据库双写一致性几种策略分析
一、背景 在高并发场景中,为防止大量请求直接访问数据库,缓解数据库压力,常用的方式一般会增加缓存层起到缓冲作用,减少数据库压力。引入缓存,就会涉及到缓存与数据库中数据如何保持一致性问题,本文将对几…...
Spring全家桶源码解析--2.6 Spring scope 限制bean的作用范围
文章目录 前言一、Scope是什么?二、Scope使用2.1 单例:2.1.1 单例Bean的特点如下:2.1.2 单例设计模式 与单例bean: 2.2 原型bean:2.2.1 原型Bean的特点:2.2.2 原型Bean的销毁: 2.3 Request bean…...
python 文本纠错库pycorrector的使用(API变更,许多介绍文章已不可用)
pycorrector是一个nice的中文检测库,在最新的版本API变更,导致许多之前的介绍文章不可用。 现将新API粘贴如下。...
【C++初阶(七)】类和对象(下)
本专栏内容为:C学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C 🚚代码仓库:小小unicorn的代码仓库&…...
Linux上C++通过LDAP协议使用kerberos认证AES加密连接到AD服务器
一.前言 记录自己在实现这个流程遇到的各种问题,因为我也是看了许多优质的文章以及组内大佬的帮助下才弄成的,这里推荐一个大佬的文章,写的非常优秀,比我这篇文章写得好得很多,最后我也是看这个大佬的代码最终才实现的…...
开源供应链管理系统 多供应商批发管理系统方案及源码输出
开发框架:PHPMySQL 后端框架:ThinkPHP 订货端:PC小程序 客户订货端:小程序 多仓库OR多供应商:多供应商 是否进销存:自带进销存 整个方案含B端订货PC、小程序端、C端小程序端下单,源码&…...
2yocto 自启动程序(服务)
yocto 自动运行主程序 文章目录 yocto 自动运行主程序1 问题现象2 问题分析:1)是否执行2)查看服务状态11)自动22)手动3)rc.local服务3 解决之道创建自定义服务自定义服务运行设置关系服务参考1 问题现象 系统启动后,自定义的主程序没有随着启动的起动,自动运行起来(界…...
AI 绘画 | Stable Diffusion 进阶 Embeddings(词嵌入)、LoRa(低秩适应模型)、Hypernetwork(超网络)
前言 Stable Diffusion web ui,除了依靠文生图(即靠提示词生成图片),图生图(即靠图片提示词生成图片)外,这两种方式还不能满足我们所有的绘图需求,于是就有了 Embeddings࿰…...
【汇编】计算机的组成
文章目录 前言一、计算机的基本组成1.1 中央处理器(CPU)1.2 内存指令和数据存储的位置计算机中的存储单元计算机中的总线地址总线数据总线控制总线 1.3 输入设备和输出设备1.4 存储设备 二、计算机工作原理三、计算机的层次结构总结 前言 计算机是现代社…...
asp.net学生宿舍管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
一、源码特点 asp.net 学生宿舍管理系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 asp.net学生宿舍管理系统1 应用技…...
[C++]Leetcode17电话号码的字母组合
题目描述 解题思路: 这是一个深度优先遍历的题目,涉及到多路递归,下面通过画图和解析来分析这道题。 首先说到的是映射关系,那么我们就可以通过一个字符串数组来表示映射关系(字符串下标访问对应着数字映射到对应的…...
OpenBMC Uboot下使用TFTP升级系统
设置TFTP服务器 setenv serverip 192.168.2.300 传入系统固件 OpenBMC的.bin文件:image-bmc,位于obmc-phosphor-image-XXXXX.static.mtd.all.tar压缩包中, image-bmc解压到TFTP服务器共享目录,传入固件: #直接输入…...
巨量千川「全域推广」指南来袭!助力商家开拓新流量
如今,在抖音上进行直播销售的商家,都希望在不影响ROI的情况下,提高整体业务水平,实现高效率的结果。然而,考虑到人货场波动和直播本身的复杂性,许多商家面临着诸如低投放效果、波动的ROI和缺乏GMV增长动力等…...
视频剪辑助手:轻松实现视频随机分割并提取音频保存
随着社交媒体和视频平台的日益普及,视频制作和分享已成为人们日常生活的一部分。无论是分享个人生活,还是展示才艺,或是推广产品,视频都是一个非常有效的工具。但是,视频制作往往涉及到大量的视频剪辑工作,…...
java注解的作用
注解 Java注解是一种用于给类、方法、字段、参数等元素添加元数据的机制,可以用来实现一些特定的功能,比如配置、文档、测试等。Java注解有两种类型:内置的和自定义的。内置的注解是Java语言或者JDK提供的,比如Override, Depreca…...
css中的hover用法示例(可以在vue中制作鼠标悬停显示摸个按钮的效果)
css中的hover 1、hover的定义 hover选择器用于选择鼠标指针浮动在上面的元素,它适用于所有元素,可以用来实现类似于js的一些功能。 2.hover的作用 css中hover属性,鼠标移到上面的时候可以激活,它可以实现悬浮元素上改变样式&a…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...
