哈喽,我是子牙。十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业。技术栈如汇编、C语言、C++、Windows内核、Linux内核。特别喜欢研究虚拟机底层实现,对JVM有深入研究。分享的文章偏硬核,很硬的那种。

手撸过JVM、内存池、垃圾回收算法、synchronized、线程池、NIO、三色标记算法…

这篇文章是谈字符串常量池的第二篇。如果上一篇你还没看,建议先回去看一下,再来看本篇

本篇文章的节奏会这样展开:首先会讲到两段Java代码创建的字符串在JVM中的存在形式,把涉及到的相关名词给大家介绍清楚。然后再引申到字符串常量池,即StringTable,详细介绍它的相关机制。最后引出上篇文章讲到的SymbolTable,把这两个Table之间的关系,及它们与常量池缓存之间的关系给大家介绍清楚。

开始……

String类

在讲硬核内容之前,我们先练个基本功:深入理解String类

这里面有两个点需要关注一下:

  1. 存储字符串内容用的是char数组
  2. 构造函数给value赋值用的是等于号,不是调用copy之类的函数,意味着两个String用的是同一个char数组,即两个String对象,字符串内容指向的是同一个

用的同一个char数组,字符串内容指向的是同一个,可能不太好理解,后面会讲到,带着这个疑问往后看吧。

练完了基本功,再来看下一个字符串在JVM中是如何存储的,看图

先不要管这个是什么样的Java代码生成的,后面会详细讲到。我们先来就这个图把相关名词解释一下,不然后面的内容就把诸位劝退了。

一个Java代码级别的字符串,在JVM中会创建两个C++对象:一个是new String对应的oop,还有一个是char数组对应的typeArrayOop。

不理解oop?你得在大脑中切换环境:new String是Java级别的对象,oop就是Java级别的对象在JVM中的存在形式。普通Java对象对应的就是oop对象,引用类型的数组对应的C++对象就是typeArrayOop。瓦特,还不理解?那你可以百度搜:oop klass

这一PA属于铺垫知识,接下来开始硬核干货…

字符串如何存储

看下这两段Java代码创建的字符串在JVM中是如何存储的

String s1 = “ziya”

其实上一PA的图就是这段Java代码创建的字符串在JVM中的存在形式,就不多解释了

JVM怎么知道要这么处理呢?当JVM执行到ldc指令就会这样处理。拓展一点,不细究:ldc指令是在编译时生成的,在link的rewrite阶段会重写为Hotspot特有的fast_ldc指令。这就是为什么有些小伙伴在debug Hotspot源码的时候在ldc指令对应的执行流下段却debug不到的原因。

String s2 = new String(“ziya”)

上面有说到两个String对象共用一个char数组,看这张图是不是就能理解了

这里面为什么会有两个String对象呢:new创建了一个String对象,ldc创建了一个String对象

这时候就有人要问了:你怎么证明呢?教你一招:IDEA debug窗口,打开这个

然后debug就可以看到JVM中创建了多少对象

为什么相等?为什么不相等?

先看这道面试题

大家先别往下滑,先自己想一想:为什么s1、s2是相等的,s3、s4是不相等的?

这里顺便说下==与equals的区别:==的意思是比较的两个字符串指向的是JVM中的同一个字符串,即内存地址相同。equals是比较的两个字符串的内容是否一样,在JVM中可能是不同的字符串。

我贴一张图,你马上就有结果了

当这四段创建字符串的Java代码执行完,在JVM中创建的对象是这样子的!可能跟你想象的不一样,少创建了很多对象。研究过的小伙伴就猜到了,是因为字符串常量池。

引入字符串常量池以后,创建字符串的流程是这样子的:先根据字符串,比如[ziya],去StringTable中查找有没有,如果有,对于s1、s2,直接返回。对于s3、s4,调用String的构造函数,完成String对象的创建。所以s1、s2相等,new String之类的代码,永远不可能相等!

如果StringTable中没有呢?将String对象保存到字符串常量池中。这里需要注意一下:字符串常量池底层也是hashtable,即用到的数据结构是上一篇说到的数组+链表,它的链表节点不是String对象,而是将String对象封装成HashtableEntry对象。我在图中没有体现这一点,因为图实在画不下了,但是大家要清楚这点。

这目前应该是全网分析字符串常量池最细致的文章不?其实你百度搜到的讲Java字符串的文章,到这个层面的,基本都是我学生写的,因为好像只要我从这个层面教过。_

与SymbolTable的关系

接下来说说StringTable与SymbolTable之间的关系

大家是否看到了一个熟悉的身影:intern!

这段代码是做什么呢?去运行时常量池缓存中去找String对象,找到了直接返回;如果没找到,就找字符串对应的Symbol对象,然后调用intern将Symbol对象转成String对象,并封装成HashtableEntry对象写入常量池。

本文篇幅已经够长,intern的底层实现留到下篇吧。SymbolTable与StringTable的细枝末节,都在intern函数中

想一想

顺便带个面试题吧

想想为什么?

瓦特?[子牙真帅]与[子牙真帅]不相等,是因为这句话本身就是谎言?

题外话

子牙手写JVM小班四期正在招生。四期新增了字节码增强+Agent,学完你就可以做JVM相关的工作,如二开arthas,自研类hsdb调试器、自研实现热更新热部署零侵入日志等黑科技…

四期完整课程包含七大专题+一个增值专题,约50多个课时。完整学完你就可以:1、用Java写一个Java虚拟机,从而深入理解运行系统的底层细节;2、有能力自行研究Hotspot源码及其他用C语言、C++写的中间件源码;3、能够用C语言、C++写任何你感兴趣的基础算法如:内存池、垃圾回收算法、主从同步算法、执行引擎、存储引擎;4、就有底子跟着我学习下半年准备开的操作系统内核班……

这套课程,横跨多个计算机学科,但只是一个学科的价格。这套课程,JVM专家、功力深厚、经验丰富的子牙老师亲授,跟我学习不踩坑,全网唯一教授虚拟机的课程…

感兴趣小伙伴可以加班班微信咨询(jvm-anan),真诚招生,无任何套路。课程试看,问题真诚解答,全部了解清楚再上车。一二三期共500多VIP加入,无一人退费,好评不断

字符串常量池,看这篇就够了(二)相关推荐

  1. python中tkinter模块窗口操作_Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)...

    本篇博文搬到个人博客:[洪卫の博客](https://sunhwee.com)上面去了,想要获得最佳阅读体验,欢迎前往 [https://sunhwee.com](洪卫の博客), 建议用电脑查看教程文 ...

  2. 字符串常量池,看这篇就够了(一)

    哈喽,我是子牙.十余年技术生涯,一路披荆斩棘从技术小白到技术总监到JVM专家到创业.技术栈如汇编.C语言.C++.Windows内核.Linux内核.特别喜欢研究虚拟机底层实现,对JVM有深入研究.分 ...

  3. JVM常量池最全详解-常量池/运行时常量池/字符串常量池/基本类型常量池,看这一篇就够了

    JVM常量池最全详解-常量池/运行时常量池/字符串常量池/基本类型常量池,看这一篇就够了! 常量池详解 1. 字面量和符号引用 1.1 字面量 1.2 符号引用 2. 常量池vs运行时常量池 3. 常 ...

  4. groovy if 判断字符串_Groovy快速入门看这篇就够了

    原标题:Groovy快速入门看这篇就够了 来自:刘望舒(微信号:liuwangshuAndroid) 前言 在前面我们学习了和两篇文章,对Gradle也有了大概的了解,这篇文章我们接着来学习Groov ...

  5. 【java进阶之路】(Java基础篇)[扩展]深入解析String.intern()及字符串常量池问题

    申明 : 此文仅仅作为个人学习使用 , 如果有人对于String.intern() 十分想要究其原理 , 请参考此文深入解析String#intern - 美团技术团队 8种基本类型的常量池都是系统协 ...

  6. Java String,看这篇就够了

    String,是Java中最重要的类.这句肯定的推断不是Java之父詹姆斯·高斯林说的,而是沉默王二说的,因此你不必怀疑它的准确性. 关于字符串,有很多的面试题,但我总觉得理论知识绕来绕去没多大意思. ...

  7. JVM之(执行引擎、字符串常量池、垃圾回收)-总结

    JVM之(执行引擎.性能监控.垃圾回收)-总结 如想了解更多更全面的Java必备内容可以阅读:所有JAVA必备知识点面试题文章目录: JAVA必备知识点面试题 注意: 本篇主要以HotSpot虚拟机为 ...

  8. java 常量字符串过长_90%的同学都没搞清楚的 Java 字符串常量池问题(图文并茂)

    字符串问题可谓是 Java 中经久不衰的问题,尤其是字符串常量池经常作为面试题出现.可即便是看似简单而又经常被提起的问题,还是有好多同学一知半解,看上去懂了,仔细分析起来却又发现不太明白. 背景说明 ...

  9. 02.字符串常量池 ? class常量池? 运行时常量池?

    java对象创建流程: 简介: 这几天在看Java虚拟机方面的知识时,看到了有几种不同常量池的说法,然后我就去CSDN.博客园等上找资料,里面说的内容真是百花齐放,各自争艳,因此,我好好整理了一下,将 ...

最新文章

  1. 【体验干货】产品经理必知:产品体验报告如何写的全而精
  2. angularjs 工具方法
  3. UE4学习-自定义角色的移动、视野旋转、设置游戏模式
  4. 2020年平均工资出炉!这个行业最高
  5. 临时抱佛脚 国产手机经典匮乏原因大解析
  6. pandas dataframe使用query进行多个条件快速筛选
  7. Inflater与findViewById()区别
  8. 程序员都应了解的 CDN 是什么?
  9. DEP机制的保护原理
  10. 多视几何_计算两幅图像之间的基础矩阵F和一副图像上的点在另一福图像上的极线L
  11. CENTOS上编译FreeSwitch
  12. KVM/QEMU libvirt 实践
  13. Feature Statistics Mixing Regularization for Generative Adversarial Networks
  14. 苹果ipad怎么刷机_苹果手机:iOS12刷机iOS12正式版刷机教程
  15. 穿越技术火线,聆听内心声音——暨龙泉第三届IT禅修营
  16. 【LeetCode】72. Edit Distance
  17. 关于几种常用的脱壳方法总结
  18. 大学生职业规划8000字_大一职业规划书8000字
  19. C语言——笨方法找“水仙花数”,步步分析
  20. 网页/公众号音乐下载

热门文章

  1. ae怎样设置gpu渲染
  2. 学计算机近视度数加深,导致近视加深的八大原因
  3. L. Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛,ac自动机+矩阵快速幂 或 BM线性递推)
  4. 使用 eMMC 闪存设备的磨损估计
  5. 记住CAD绘图快捷键,让你快速当大师
  6. 网页下拉框智能诱导输入
  7. Unicode编码表到GB2312编码表映射表
  8. 当今软件发展的现状非常适合 Cloud Native 环境 1
  9. R语言数据科学:变量选择(一)逐步回归法
  10. 18.鸡尾酒疗法C语言