常量池(后期专门找一篇说一下)

1、class文件中

​ 通过命令:javap -verbose XXX

Constant pool:#1 = Methodref          #23.#50        // java/lang/Object."<init>":()V#2 = Methodref          #22.#51        // com/luban/ziya/string/TestIntern.test5:()V#3 = String             #52            // 1
....

​ 在硬盘上

2、运行时常量池

​ 一般说的常量池就是指这儿

​ InstanceKlass的一个属性

​ ConstantPool* _constants;

​ 方法区(元空间)

3、字符串常量池

​ 即String Pool,但是JVM中对应的类是StringTable,底层实现是一个hashtable,看代码

class StringTable : public Hashtable<oop, mtSymbol> {
……

​ 在堆区

Hashtable是如何存储字符串的

例如 name = “aaa”,sex = “man”,zhiye = “teacher”

假设 name进行hashValue后是 11,sex的hashValue = 13,zhiye的hashValue = 11,

存储方式可以参考下图

根据key从hashtable中查数据

​ 1、将key通过hash算法计算成hashValue(name:11)

​ 2、根据11去hashtable中去找,如果index=11关联的元素只有一个,直接返回

​ 3、如果是多个,根据链表进行遍历,比对key


java中的字符串在jvm中是如何存储的

StringTable的Key的生成

1、根据字符串以及字符串的长度计算出hashValue

2、根据hashValue计算出index,这个index就是key

hashValue = hash_string(name, len);
index = hash_to_index(hashValue);// Pick hashing algorithm
unsigned int StringTable::hash_string(const jchar* s, int len) {return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :java_lang_String::hash_code(s, len);
}// Bucket handling
int hash_to_index(unsigned int full_hash) {int h = full_hash % _table_size;assert(h >= 0 && h < _table_size, "Illegal hash value");return h;
}

StringTable的Value的生成

将Java的String类的实例instanceOopDesc(String类在JVM中的存在形式)封装成HashtableEntry(就是一个结构体)

struct HashtableEntry {INT_PTR hash;void* key;    //hashValuevoid* value;   //instanceOopDescHashtableEntry* //next;};
HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string()); // 这里的string()指的就是instanceOopDesc
add_entry(index, entry);template <class T, MEMFLAGS F> HashtableEntry<T, F>* Hashtable<T, F>::new_entry(unsigned int hashValue, T obj) {HashtableEntry<T, F>* entry;entry = (HashtableEntry<T, F>*)BasicHashtable<F>::new_entry(hashValue);entry->set_literal(obj);return entry;
}

​ **String有时候会存储到StringTable,有的时候不会,**后面会有StringBuffer的案例,可以看到对象的值直接就是,而不是指向常量池,这个与与intern还有渊源,

​ 下面是周志明大佬书中的一段内容(这本书强烈建议Java开发者读一下 这本书强烈建议Java开发者读一下 这本书强烈建议Java开发者读一下

String.hashcode()

​ String类重写了hashcode方法

public int hashCode() {int h = this.hash;if (h == 0 && this.value.length > 0) {char[] val = this.value;for(int i = 0; i < this.value.length; ++i) {h = 31 * h + val[i];}this.hash = h;}return h;
}

​ 可以看出String的hashcode与String的内容是有关系的,因此下面的代码的hashcode是相等的

public class TestHashcode {public static void main(String[] args) {String s1 = "11";String s2 = new String("11");System.out.println(s1.hashCode());System.out.println(s2.hashCode());}
}

不同方式创建字符串在JVM中的存在形式

​ String 是用一个字符数组来存储值的,基本类型的数组的元信息存放在TypeArrayKlass中,它的对象是存在TypeArrayOopDesc中。

 private final char value[];

字符数组在JVM中是怎样存在的

运行以下代码,通过HSDB查看

public class CharArray {public static void main(String[] args) {char[] arr = new char[]{'1', '2'};while (true);}
}

可以看到元信息是存储在TypeArrayKlass中


一个双引号

以下代码生成了几个oop

String s1 = "1";

生成两个oop 一个String

1、TypeArrayOopDesc char数组

2、InstanceOopDesc String对象

证明

debug以下代码

此时内存中的char[] 和String的数量如下图

当执行完第20行后,结果如下图,可以看到二者均 +1

接下来图解一下,以以下代码为例

public static void test1() {String s1 = "11";
}


两个双引号

以下代码生成了几个oop

String s1 = "2";
String s2 = "2";

此时你是不是想说三个

继续debug以下代码

执行完24行时

执行完25行时

可以发现增加了两个

干了两晚,带你探索那讲不清的字符串相关推荐

  1. “阿里技术Leader拿那么多钱,每天都干些啥?”带50多人团队,我总结了14点体会!

    •   推酷-技术 点击" 技术领导力 "关注 ∆ 每天 早上8:30 推送 来阿里两年多了,从 1 个人,到现在带领 50 多人的团队,走过了一段艰辛的充满变化的带团队历程,在这 ...

  2. “阿里技术Leader拿那么多钱,每天都干些啥?”带50多人团队,我总结了14点体会!...

    点击"技术领导力"关注∆  每天早上8:30推送 来阿里两年多了,从 1 个人,到现在带领 50 多人的团队,走过了一段艰辛的充满变化的带团队历程,在这里总结下自己过去两年带 15 ...

  3. 带你探索条形码世界的奥秘

    带你探索条形码世界的奥秘 序 二维码也就是QR码受所谓的移动互联网吵得也比较火,但是同学我奉劝你还是把一维的先搞懂吧.首先要说的就是印在商品上的条形码 就仅仅是一串竖条而已没什么玄机,对印刷面也无特定 ...

  4. 10分钟带你探索css中更为奇妙的奥秘

    10分钟带你探索css中更为奇妙的奥秘

  5. 三角形面积=SQRT(S*(S-a)*(S-b)*(S-c)) 其中S=(a+b+c)/2,a、b、c为三角形的三边。 定义两个带参的宏,一个用来求area, 另一个宏用来求S。 写程序,在程序中用带

    题目描述 三角形面积=SQRT(S*(S-a)*(S-b)*(S-c)) 其中S=(a+b+c)/2,a.b.c为三角形的三边. 定义两个带参的宏,一个用来求area, 另一个宏用来求S. 写程序,在 ...

  6. .Net Discovery系列文章阅读索引--带你探索未知的.Net世界

    .Net Discovery系列文章是讲述.Net平台机制的文章,目前已有12篇,分别讲述了.Net垃圾收集.实时编译.字符串等部件的机制,现在推出1周年之际总结文章阅读索引,希望对大家有所帮助.   ...

  7. (带区号)座机号正则_字符串处理之正则表达式(通俗易懂)

    背景图为:网易Bgwan/Lofter&&:click 写在前面 很久没有更新内容了,本篇准备介绍一些基础实用性的内容,-字符串处理之正则表达式 字符串是编程时涉及到的最多的一种数据结 ...

  8. 编写一个C程序,实现以下功能:编写一个常规的函数和一个递归函数,两个函数均能将输入的一个字符串以按反序形式的字符串作为返回值。在main函数中输入一行字符串,分别调用两个函数,输出反序后的字符串。

    题目要求: 编写一个C程序,实现以下功能:编写一个常规的函数和一个递归函数,两个函数均能将输入的一个字符串以按反序形式的字符串作为返回值.在main函数中输入一行字符串,分别调用两个函数,输出反序后的 ...

  9. 将两个数组不同的元素拼接成一个字符串

    1.创建两个长度为10的数组,数组内元素为随机生成的.不重复的 1-100之间的整数. 2.定义一个方法,传入两个数组,方法中将两个数组不同的元素拼接成一个字符串,并且将该字符串以及字符串的长度输出到 ...

最新文章

  1. 【Linux】Linux简单操作之压缩解压
  2. ABAP_Excel 处理总结(二)
  3. CentOS 6.5 升级 PHP 到5.6
  4. Struts2——namespace、action、以及path问题
  5. 印刷(烫金)缺陷在线检测系统
  6. 微软发布Visual Studio Mac预览版
  7. 数据结构与算法学习网
  8. ECSHOP 大商创 对接易支付接口
  9. vue实现留言板的功能_vue初探-简易留言板
  10. 删除python的注册表_python如何清除注册表
  11. centos7安装docker并配置镜像加速
  12. C语言中access函数的使用
  13. C64+ cache资料集(更新中)
  14. 启动rabbitmq后台管理插件出错 /usr/lib64/erlang/erts-10.3.5.12/bin/beam.smp: error while loading shared librari
  15. 微信停止为苹果服务器,苹果用户注意!iOS成微信封号重灾区 赶快停止使用你的双客户端...
  16. 【无标题】求各大ios shsh版本!能不能给大哥?
  17. 无监督关键短语的生成问题博客07--create_vocabulary.py的分析
  18. 烦人的IE浏览器兼容问题,F12开发模式正常,普通模式就不行
  19. UML状态图 2021.07.18
  20. 数据分析-各种图表的使用场景(网易云课堂笔记)

热门文章

  1. apa引用要在文中吗_APA写作规范究竟有多细节?
  2. 安装Android应用至SD卡
  3. 记住CAD绘图快捷键,让你快速当大师
  4. js网页简繁体切换cookie记录状态
  5. 每天学习一个设计模式(九):创建型之建造者模式
  6. [运动控制算法]Pure Pursuit纯路径跟踪算法
  7. 考研英语阅读理解总结
  8. IS审计师执行风险评估的主要原因
  9. 0017 正方体的表面积和体积
  10. Android高工:细说 Android 多线程,探究原理知其所以然