JVM——3.StringTable字符串常量池

这篇文章我们来讲一下StringTable字符串常量池

目录

1.引例

2.StringTable的特性

3.StringTable的位置

4.StringTable的垃圾回收、

5.StringTable性能调优

6.总结

1.引例

首先,我们来看下面的这段程序,请思考最终的输出结果。

输出结果:

解释:

首先,我们的程序会被JDK中的编译器编译成java的二进制字节码文件,然后通过类加载器将其加载到JVM的内存的栈中,其中会生成一个常量池(就是一张常量池表),里面放在这个类编译后的各种字面量和符号注意,此时常量池中只存储了这些字面量的符号,没有生成具体对象。举个例子来说,就比如第7行的a,它在常量池中可能就是用一个符号25来表示的,没有具体的String类型的变量a,也不会开辟新的空间来存储a。然后根据程序计数器来一步一步的运行该程序。当执行到这一行,常量池中的信息会被加载到运行时常量池中,常量池中原本记录的符号也会变为真实的地址,即符号25变为地址25,并且会在堆中开辟一块空间存储String类型的变量a,这块开辟的空间就称为串池(即字符串常量池,即StringTable),它在堆中,其中里面一开始时是空的,当运行到这一行时,会把a放入里面,a的地址为25(假设的)。这就是整体的流程。然后就是依次在串池中放入b和ab。当执行到第10行时,它创建的是一个StringBuild对象,放入s1的值即a,然后调用StringBuilder的方法,进行字符串拼接。然后再创建一个新的String对象,里面放的就是拼接后的结果,即ab,很明显,s4中的ab是在堆中的,而"=="符号判断的是两个对象的地址是否相等,所以很明显,第14行输出false。当程序运行到第11行时,jvm会先在串池中找是否有ab,找到了,那么就不再创建新的对象了,就直接把这个ab的地址赋予s5,所以第15行输出true。下面再看第9行,这种字符常量相加的是直接相加的,没有创建对象调用方法。所以最后相加的结果就直接放在运行时常量池的串池中,所以第14行输出false,第15行输出true。对比着看第9行和第10行,第9行javac在编译时进行了优化,因为第9行是两个字符常量相加的,最终的结果是一定的,不会变的,所以就直接加,然后放到串池中。而第10行是因为这是两个变量相加,不确定最后的结果,所以就使用了StringBuilder类对象来进行操作。多说一句,字符串还具有延迟实例化的特点,具体来说就是在编译结束后不会直接实例化该字符串,直到代码运行到这一句的时候才会实例化出具体的字符串,并放入内存中。

下面再来看一下第12行,第12行调用了intern方法。这个方法的作用是主动将串池中还没有的字符串对象放入串池。第12行是s4调用了intern方法的,我们知道,s4的引用是指向堆内存中的ab的,s4调用这个方法,jvm会先看运行时常量池中有没有ab这个字符对象,如果没有,那么就把堆中的ab放入到运行时常量池中,注意,放入后,堆中就没有这个ab了;如果jvm发现运行时常量池中有这个ab对象,那么就直接把s6的引用指向它。这就是intern的作用。

这里关联一下字符串的不可变性,字符串的不可变性是一个引用多个对象,而这里将的是多个引用一个"对象"(不是一个对象,仅仅是值相等而已)

2.StringTable的特性

下面看一下StringTable的特性:

  1. 常量池中的字符串仅是符号,第一次用到时才变为对象
  2. 利用串池的机制,可以避免重复创建字符串对象
  3. 字符串变量拼接的原理是StringBuilder (1.8)
  4. 字符串常量拼接的原理是编译期优化
  5. 可以使用intern方法,主动将串池中还没有的字符串对象放入串池

注意:在jdk1.8以后,intern方法是把堆中对象的值挪到串池中,1.8以前,是将堆中的值复制一份,然后放到串池中。这一点需要注意。


3.StringTable的位置

下面来看一下StringTable的位置,如下图所示:

如图所示,在jdk1.8以后,StringTable就在堆中了。StringTable就是字符串常量池!

4.StringTable的垃圾回收、

这里我们只需要了解StringTable是可以进行垃圾回收的,具体是怎么回收的,我们后面将GC的时候会具体的讲,这里就不多说了。

5.StringTable性能调优

StringTable的底层的哈希表,StringTable进行性能调优就是要调整哈希表。

性能调优的方法:

  • 调整 -XX:StringTableSize=桶个数
  • 考虑将字符串对象是否入池

6.总结

这篇文章我们主要讲解了StringTable。下面总结一下。

StringTable,即字符串常量池,是存储字符串对象用的,在堆中。一个字符串,在被编译后,是不会创建对象的,仅仅只会在常量池中存储一个符号,只有当运行到这行代码的时候,才会在字符串常量池中创建对象,这就是字符串的懒加载,也是延迟加载。然后在字符串常量池中,也可以避免创建重复的对象。即如果StringTable中已经有了该对象,那么如果再有引用需要创建相同值的对象的时候,该引用会直接指向这个对象,就避免了重复创建。StringTable还可以进行垃圾回收。还讲述了StringTable的性能调优的两点策略。这就是本篇文章的所有内容。


 

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

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

相关文章

Multitor:一款带有负载均衡功能的多Tor实例创建工具

关于Multitor Multitor是一款带有负载均衡功能的多Tor实例创建工具,Multitor的主要目的是以最快的速度完成大量Tor进程的初始化,并将大量实例应用到我们日常使用的程序中,例如Web浏览器和聊天工具等等。除此之外,在该工具的帮助下…

常用设计模式总结 + 实例

工厂模式 工厂函数通常是指一个函数,它用来创建和返回其他函数或对象的实例。 人话: 当new Class 或 Function 时,根据传入的参数,而返回不同的值,这就是工厂模式。 (所以可以说,这是我们开…

vscode如何设置文件折叠

随着项目的不断迭代开发,复杂度越来越高,配置文件越来越多,导致vscode左侧文件列表展示非常不直观,幸好可以通过文件折叠来简化展示效果,把同类相关的文件折叠在一块展示,方便查看配置文件。配置好后的效果…

React 开发一个移动端项目(2)

配置基础路由 目标:配置登录页面的路由并显示在页面中 步骤: 安装路由: yarn add react-router-dom5.3.0 5 和 6 两个版本对组件类型的兼容性和函数组件支持有所改变,在这里使用的是 5。 和路由的类型声明文件 yarn add types…

VTK 基础入门 ( 一 ) 相机设置

/** 相机 SetClippingRange()/SetFocalPoint() / SetPosition()分别用于设置相机的前后裁剪平面、焦点和位置。 ComputeViewPlaneNormal()方法是根据设置的相机位置、焦点等信息,重新计算视平面 (View Plane)的法向量。 一般该法向量与视平面是垂直…

基于 kubernetes+docker构建高可用、高性能的 web 、CICD集群

文章目录 一、项目架构图二 、项目描述三、项目环境四、环境准备1、IP地址规划2、关闭selinux和firewall3、配置静态ip地址4、修改主机名5、升级系统(可做可不做)6、添加hosts解析 五、项目步骤1、设计整个集群的架构,规划好服务器的IP地址&a…

Postgresql中检测内存越界或use after free的简便方法

1 使用场景 在Postgresql的内存管理模块中,最常用的aset.c提供的内存池实现,该实现提供了两个非常实用的开关来解决常见的内存越界问题: memdebug.c * About CLOBBER_FREED_MEMORY:** If this symbol is defined, all freed memory is over…

AIGC专栏6——通过阿里云与AutoDL快速拉起Stable Diffusion和EasyPhoto

AIGC专栏6——通过阿里云与AutoDL快速拉起Stable Diffusion和EasyPhoto 学习前言Aliyun DSW快速拉起(新用户有三个月免费时间)1、拉起DSW2、运行Notebook3、一些小bug AutoDL快速拉起1、拉起AutoDL2、运行Notebook 学习前言 快速拉起AIGC服务 对 用户体…

Debian 12快速安装图解

文章目录 Debian 12安装图解创建虚拟机安装系统登录并用光盘离线安装sudo、curl解决Linux下sudo更改文件权限报错保存快照debain添加在线源(配置清华源)参考 Debian 12安装图解 Debian选择CD安装非常慢,本次安装选择DVD离线安装。 下载 https://www.debian.org/CD…

大范围XSS扫描工具:XSS-Freak,BurpSuite随机用户代理,Hades 静态代码审核系统

大范围XSS扫描工具:XSS-Freak,BurpSuite随机用户代理,Hades 静态代码审核系统。 #################### 免责声明:工具本身并无好坏,希望大家以遵守《网络安全法》相关法律为前提来使用该工具,支持研究学习…

【AIGC】Stable Diffusion Prompt 每日一练0916

一、前言 1.1 写在前面 本文是一个系列,有点类似随笔,每天一次更新,重点就Stable Diffusion Prompt进行专项训练,本文是第022篇《Stable Diffusion Prompt 每日一练0916》。上一篇《Stable Diffusion Prompt 每日一练0915》 1.…

ES6中新增加的Proxy对象及其使用方式

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ Proxy对象的基本概念Proxy对象的主要陷阱(Traps) ⭐ 使用Proxy对象⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来…

开源项目-SeaTunnel-UI数据集成系统

哈喽,大家好,今天给大家带来一个开源项目-SeaTunnel-UI数据集成系统 系统主要有任务配置,任务实例,数据源,虚拟表,用户管理等功能 登录 数据源 mysql数据源配置参数说明 kafka参数配置 mysqlcdc配置参数说明 虚拟表

【自学开发之旅】Flask-标准化返回-连接数据库-分表-orm-migrate-增删改查(三)

业务逻辑不能用http状态码判断,应该有自己的逻辑判断。想要前端需要判断(好多if…else),所以需要标准化,标准化返回。 json标准化返回: 最外面:data,message,code三个字段。 data:返回的数据 co…

索引-动图演示存储过程

索引 二叉树存储过程演示 BThree存储过程 sql二级索引搜索过程 Id是唯一键,聚集索引 只存在一个 Name是二级索引 可以存在多个 第一种效率更高,不需要回表

【红包雨接口设计】

一、服务器地址 http://rb.atguigu.cn 二、公共请求头参数 参数名称类型是否必选描述tokenString是用户唯一标识 备注:为了方便我们今天演示,服务端接受所有token。 三、接口 1. 创建红包雨 请求方式:GET请求地址:/api/v1/se…

Java + Selenium + Appium自动化测试

一、启动测试机或者Android模拟器(Genymotion俗称世界上最快的模拟器,可自行百度安装) 二、启动Appium(Appium环境安装可自行百度) 三、安装应用到Genymotion上,如下图我安装一个计算机的小应用&#xff0c…

epoll及总结

使用方法:基本与poll相同 生成对象改为epoll() 将所有事件类型改为EPOLL类型epll特点 epoll 效率比select poll要高 epoll监控数量比select 要多 epoll的触发方式比pollduo(EPOLLET边缘触发)""" poll_server.py 完成tcp并发服务 Io多路复用实现并发建立fileno -…

webpack:css-loader和style-loader关系

测试 当我们webpack 的 rules 啥都没配置的时候 const path require(path);module.exports {entry: ./src/index.js,output: {filename: index.js,path: path.resolve(__dirname, dist)},module: {rules: []} };我们在 js 中导入了 css,发现报错,因为…

TypeScript项目配置

前言 我们需要建立tsconfig.json 作用 用于标识 TypeScript 项目的根路径; 用于配置 TypeScript 编译器; 用于指定编译的文件。 重要字段 files - 设置要编译的文件的名称; include - 设置需要进行编译的文件,支持…