Java 深入JVM分析String StringTable

文章目录

基本特性:

1、字符串常量池Jdk1.7之前位于方法区,1.7开始位于堆

2、字符串常量池中同样的数据只存储一份(固定大小HashTable存储数据)

3、使用 -XX:StringTableSize 可设置大小,不会像HashMap一样动态扩容,值太小造型Hash冲突严重,调用String.interns时性能会大幅下降

4、Jdk1.8中默认大小60013,1009是可设置最小值

字符串拼接:

1、通过StringBuilder的append()方法拼接字符串,自始至终只会创建一个StringBuilder的对象

2、使用String的字符串拼接,每次拼接都会创建一个StringBuilder和String对象,内存占用增大,也会增加GC频率

字符串拼接优化:

1、理论上初始化StringBuilder对象时,指定大小,从而设的数组大小,可以提高效率(减少扩容、复制次数)

2、但是,通过测试,发现设定大小与不设定,耗时相差无几(毫秒)

intern方法的使用:

情况一:intern方法会从字符串常量池中查询当前字符串是否存在,若不存在,则会将当前字符串放入常量池中并把地址返回栈中引用,存在则将地址返回给栈中引用。

String s1 = “JavaEEHadoop”; //在字符串常量池中创建 “JavaEEHadoop”String s2 = new String(“JavaEEHadoop”).intern(); //会将字符串常量池中 “JavaEEHadoop” 地址 返回s2System.out.println(s1 == s2); true

情况二:如果对象在堆中已经创建了,字符串常量池中就不需要再创建新的对象了,而是直接保存堆中对象的引用,也就节省了一部分的内存空间

下述情况适用于Jdk1.7、1.8

/*** 此代码会在字符串常量池中 创建 “JavaEE”、”Hadoop“* 会使用StringBUilder来拼接,最后执行toString方法* * 此时在堆中是存在值为 “JavaEEHadoop” 的字符串对象的*/String s1 = new String(“JavaEE”) + new String(“Hadoop”);/*** 由于s1在堆中已存在,因此为了节省空间,字符串常量池中并不会创建 “JavaEEHadoop”* 而是保存 堆中对象的引用*/s1.intern();/*** 由于此刻字符串常量池中已存在,因此s2会指向常量池中 堆中对象的引用*/String s2 = “JavaEEHadoop”;System.out.println(s1 == s2); true

是否引用同一份对象?

String s1 = “JavaEE”;String s2 = “Hadoop”;String s3 = “JavaEEHadoop”;/*** 编译器优化 为 JavaEEHadoop,s3 == s4 为true,在字符串常量池中同一份*/String s4 = “JavaEE” + “Hadoop”;System.out.println(s3 == s4); true/*** 如果拼接符号的前后出现了变量* 1、StringBuilder.toString中 s = new StringBuilder();* 2、s.append(“JavaEE”);* 3、s.append(“Hadoop”);* 4、s.toString(); –>类似于 new String(char[])* 但跟String s = new String(“JavaEEHadoop”)不一样* 由于StringBuilder.toString中new String中参数是char[]数组* 因此并不会在字符串常量池中创建 ”JavaEEHadoop“*/String s1 = “JavaEE”; //字符串常量池中 “JavaEE”String s2 = “Hadoop”; //字符串常量池中 “Hadoop”String s3 = “JavaEEHadoop”;String s4 = s1 + “Hadoop”; String s5 = s1 + s2;System.out.println(s3 == s4); falseSystem.out.println(s3 == s5); false/*** final修饰的string变量相加时,编译器会优化为 ab,不会用StringBuilder拼接* s11 == s12 为true,在字符串常量池中同一份* s12会被编译器优化为 “ab”*/final String s1 = “a”;final String s2 = “b”;String s3 = “ab”;String s4 = s1 + s2;System.out.println(s2 == s4); true

创建了几个对象?

/*** 创建了1个或2个* 执行步骤,对应字节码步骤* * 1、堆中开辟String对象空间 new #8 * 2、如果 “ab” 在字符串常量池中存在,那么久不创建,如果不存在则创建* 3、初始化String对象*/String s1 = new String(“ab”);/*** 字节码*/步骤1、new #17 步骤1、dup步骤2、ldc #14 步骤3、invokespecial #18 /*** 如果字符串常量池中 “a”、”b”不存在,那么会创建6个对象* * 执行步骤对应字节码步骤* 1、堆中开辟StringBuilder对象空间,初始化StringBuilder对象 * 2、堆中开辟String对象空间* 3、在字符串常量池中创建 “a”* 4、初始化String对象* 5、执行append方法* * 6、堆中开辟String对象空间* 7、在字符串常量池中创建 “b”* 8、初始化String对象* 9、执行append方法* 10、执行toString方法* StringBuilder对象toString方法执行说明,由于返回的是String对象,因此会执行toString方法* 11、堆中开辟String对象空间* 由于调用的是new String(char[])构造方法* 因此并不会在字符串常量池中创建 “ab”*/String s1 = new String(“a”) + new String(“b”);/*** 字节码文件*/步骤1、new #8 步骤1、dup步骤1、invokespecial #9 步骤2、new #17 步骤2、dup步骤3、ldc #12 步骤4、invokespecial #18 步骤5、invokevirtual #10 步骤6、new #17 步骤6、dup步骤7、ldc #13 步骤8、invokespecial #18 步骤9、invokevirtual #10 步骤10、invokevirtual #11 步骤11、new #80 步骤11、dup//我们可以看到toString方法中并没有 在字符串常量池中创建 “ab”aload_0getfield #234 iconst_0aload_0getfield #233 invokespecial #291 areturn

提示:这里对文章进行总结:

建议大家不要卷、不要卷、不要卷

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年6月16日
下一篇 2022年6月16日

相关推荐

  • 未来几年武汉房价有没有上涨的空间?

    有,但是上涨空间不会太大,因为武汉所处区域并非经济繁荣区,缺少城市群及旅游区的宏观概念,因此城市自身实力再强,也是单兵作战,不会超出区域整体房价过高。 加之一些自身原因,比如武汉已…

    2022年5月7日
  • iPhone11只要1850元?群友:别买!这是ID机,有隐藏ID

    粉丝在某平台看到一台iPhone11 128GB,该机只要1850元。于是发到群里问大家是否值得入手。大家的回复出奇的一致,那就是不能买。因为从卖家的描述中就能看出,这台iPhon…

    2022年7月1日
  • map的常用用法详解

    map是一种映射,是常用的STL容器。(map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器)) 如需使用,需要加一个map头文件。 1.map的定义: m…

    2022年6月13日
  • matplotlib 刻度线的位置和数值的动态调整

    在一般情况下,刻度线的位置和刻度线相应位置处的数值(刻度标签)是由生成图形的原始数据决定的。如果需要调整刻度线的位置和对应的数值,那么可以使用函数 xticks()和 yticks…

    2022年6月14日
  • 身处逆境,如何翻盘?

    突然一刻就觉得处在了一种很糟糕的局面,家庭、工作、孩子一切都极端不顺利,自己的情绪因此受到很大影响,绝望、焦虑、不知所措,再一考虑自己的年龄,明明在不惑的年纪,却遭遇着巨大的困惑,…

    2022年5月6日
  • 班主任直言:写作文是有公式的,妈妈一定要告诉孩子!比如写游记、写

    班主任直言:写作文是有公式的,妈妈一定要告诉孩子!比如写游记、写景、写物、写事、写人等8大写作技巧,提高孩子的写作水平。家有孩子的赶紧收藏!没有笨孩子,只是没掌握好方法,没事让孩子…

    2022年9月18日
  • 君子兰的养殖方法和注意事项(家养君子兰的技巧)

    君子兰作为一种室内盆栽,它的外观美丽大方,有着很好的观赏性,并且君子兰还有不错的净化空气能力以及药用价值,在室内养殖方面,受到了很多人的喜爱,但是我们在养殖君子兰的时候都会遇到一些…

    2022年5月6日
  • python实现小说阅读器

    示例简介 本文使用python语言开发了一个小说阅读器,通过小说书号抓取全部章数的内容,并保存到计算机上,同时也可以通过阅读器读取相应章数的内容; 预览效果:根据填写的小说书号,分…

    2022年6月16日
  • 想买18W左右的SUV,女孩开,求推荐?

    女孩开的SUV,用于城市代步和周边旅游的话不用选太大的,不然城市代步的时候倒车什么的不方便,然后周边旅游的时候也不用带什么东西,那么就可以选择一款小型SUV。 预算在18-20万我…

    2022年7月25日
  • 汗是人体的“晴雨表”,中医:5个部位出汗,或要引起重视

    出汗是一种正常的生理现象,是维持人体恒定的基础,也算是人体新陈代谢的一种排泄方式,尤其是炎热的季节,很多人出汗特别的明显。 当外界的气温升高时,或者是人体内部产热增加时,为了更好地…

    2022年9月19日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息