当前位置: 首页 > news >正文

制作网站404页面百度搜索风云榜明星

制作网站404页面,百度搜索风云榜明星,网站设计主流尺寸,做公司网站需要什么StringTable 特性 常量池中的字符串仅是符号,第一次用到时才变为对象 利用串池的机制,来避免重复创建字符串对象 字符串变量拼接的原理是 StringBuilder (1.8) 字符串常量拼接的原理是编译期优化 可以使用 intern 方法&#…

StringTable

特性

  • 常量池中的字符串仅是符号,第一次用到时才变为对象

  • 利用串池的机制,来避免重复创建字符串对象

  • 字符串变量拼接的原理是 StringBuilder (1.8)

  • 字符串常量拼接的原理是编译期优化

  • 可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池

    • 1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串池中的对象返回
    • 1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池, 会把串池中的对象返回
场景1
package com.vmware.jvm;public class Demo1 {public static void main(String[] args) {String a="a";String b="b";String c="ab";}
}
  • 在JVM中会预先准备好一块内存空间 StringTable [] ,其内容为空 数据结构采用HashTable
  • 此时符号a、b、ab都还是常量池中的符号,还没有变为java字符串对象
  • ldc #2会将a符号变为a字符串对象,然后判断StringTable中是否存在字符串a,如果不存在则添加到StringTable中,否则直接使用StringTable中的串
  • ldc #3会将b符号变为b字符串对象 然后判断StringTable中是否存在字符串b,如果不存在则添加到StringTable中,否则直接使用StringTable中的串
  • ldc #4会将ab符号变为ab字符串对象 然后判断StringTable中是否存在字符串ab,如果不存在则添加到StringTable中,否则直接使用StringTable中的串
  • 执行结束后: StringTable [“a”,“b”,“ab”]

❗️ 注意:字符串不会预先加载到StringTable中,而是当使用该字符串时才会被加载,其行为为懒惰型

反编译代码

      stack=1, locals=4, args_size=10: ldc           #2                  // String a  2: astore_1                                       3: ldc           #3                  // String b  5: astore_2                                       6: ldc           #4                  // String ab 8: astore_3                                       9: return
场景2
public class Demo1 {public static void main(String[] args) {String a = "a";String b = "b";String c = "ab";String d = a + b;}
}

反编译如下

9: new           #5                  // class java/lang/StringBuilder //new StringBuilder()
12: dup
13: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V 调用无参构造方法
16: aload_1                           //从LocalVariableTable中加载1号槽的变量"a"
17: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; //调用StringBuild().append("a")
20: aload_2                           //从LocalVariableTable中加载2号槽的变量"b"
21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;//调用StringBuild().append("b")
24: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
//调用toString()方法  -> new String("ab");
27: astore        4                   //存储到LocalVariableTable4号槽

StringBuild toString方法源码

 	@Overridepublic String toString() {// Create a copy, don't share the arrayreturn new String(value, 0, count);}

相当于

new StringBuild().append("a").append("b").toString();

调用new String(“ab”)后相当于在堆中创建了一个新的字符串对象,所以

d==c  //false d在堆中 c在StringTable中
编译期优化

javac会认为e的结果是确定的,所以进行了编译期优化

String e = "a" + "b";

反编译

 29: ldc           #4                  // String ab
  • 相当于直接从常量池中加载符号ab
c==e //true  c第一次被加载到StringTable中,e与c相同不会再次进入StringTable,e指向的地址与c的地址相同
字符串延迟加载证明

在这里插入图片描述

  • 可以使用IDEA开启debug模式后,使用内存检测功能,观察字符串的数量
package com.vmware.jvm;public class Demo2 {public static void main(String[] args) {System.out.println();//2433System.out.println("a");//2434System.out.println("b");//2235System.out.println("c");//2436System.out.println("a");//2436System.out.println("b");//2436System.out.println("c");//2436}
}
  • 代码每执行一行,String的数量+1,说明字符串没有进行预加载
  • 第二次使用字符串时,String的数量没有增加
场景三
public class Demo3 {public static void main(String[] args) {String x="ab";String s = new String("a") + new String("b");//实际上利用StringBuild的append方法进行拼接,"a" "b"会被先加载到串池中 StringTable=["ab","a","b"]String s2 = s.intern();//入池失败   s2-> table."ab"  s-> heap."ab"  x-> table."ab"System.out.println(s == x);//falseSystem.out.println(s2 == x);//true}
}
  • intern方法在jdk1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,并返回串池中的对象
  • 在jdk1.6中将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池, 会把串池中的对象返回
String s2 = s.intern();//s2 -> table  s-> heap
  • intern方法注释:调用 intern 方法时,如果池已包含与equals(Object)方法比较后相等的String字符串,则返回池中的字符串。否则,此String对象将添加到池中,并返回对此String对象的引用
问题
package com.vmware.jvm;public class Demo4 {public static void main(String[] args) {String s1 = "a";String s2 = "b";String s3 = "a" + "b";String s4 = s1 + s2;String s5 = "ab";String s6 = s4.intern();//问System.out.println(s3 == s4);//false  s3在编译期进行优化 s3="ab" 在StringTable中  s4=new StringBuild().append("a").append("b"),toString() 在堆中System.out.println(s3 == s5);//true s3进入StringTable s5发现StringTable中有"ab"则指向Table中的地址System.out.println(s3 == s6);//true  s4调用intern方法后入池失败,返回池中的"ab"所以 s6即为池中的"ab"String x2 = new String("c") + new String("d");String x1 = "cd";x2.intern();//将对象new String("cd")放入池中,入池失败//问 如果调换了后两行的位置呢,如果是jdk1.6呢System.out.println(x1 == x2);//jdk1.8 false x2指向堆,x2调用入池方法后入池失败 x2指向堆 x1指向StringTable//交换位置  x2入池成功,x2指向池中的cd  x1指向池中的c 所以为true//jdk1.6 首先在堆中new String("cd") 然后调用intern方法,会对堆中的对象拷贝一份入池,而x2仍然指向堆中的对象  x1发现池中有"cd"直接使用池中的对象,所以为false}
}
String Table的位置

在这里插入图片描述

  • jdk1.6:永久代
  • jdk1.7、1.8:堆内存

🔖 为什么要将StringTable从永久代移动到堆中?

因为永久代的内存只有当触发FullGC的时候才会回收,而堆内存在触发MinorGC的时候就会触发回收,由于StringTable使用比较频繁,所以JVM工程师对位置进行了移动

垃圾回收
package com.vmware.jvm;/*** @apiNote StringTable垃圾回收延时* -Xmx10m:设置堆大小为10m* -XX:+PrintStringTableStatistics 打印StringTable信息* -XX:+PrintGCDetails -verbose:gc 打印垃圾回收信息** 初始信息* StringTable statistics:* Number of buckets       :     60013 =    480104 bytes, avg   8.000* Number of entries       :      1711 =     41064 bytes, avg  24.000  //StirngTable中的key-value对 1711* Number of literals      :      1711 =    154040 bytes, avg  90.029  //字符串数量1711* * 添加10000个字符串到StringTable后* StringTable statistics:* Number of buckets       :     60013 =    480104 bytes, avg   8.000* Number of entries       :      5845 =    140280 bytes, avg  24.000* Number of literals      :      5845 =    353352 bytes, avg  60.454* 数量小于11711,说明StringTable内进行了垃圾回收*/
public class Demo6 {public static void main(String[] args) {int i = 0;try {for (int j = 0; j < 10000; j++) {String.valueOf(j).intern();}} catch (Throwable e) {e.printStackTrace();} finally {System.out.println(i);}}
}
性能调优

StringTable采用的数据结构为哈希表,所以可以通过调整主数组的大小来减小哈希碰撞的概率,进而提升效率

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

如果程序运行期间会产生大量字符串,并且字符串重复数量较多,可以考虑将字符串进行入池操作,减少内存开销

入池前

在这里插入图片描述

入池后
在这里插入图片描述

http://www.shuangfujiaoyu.com/news/31054.html

相关文章:

  • 宁波营销型网站建设浏览广告赚佣金的app
  • 快速建站公司竞价托管推广代运营
  • 个人网站 免费空间百度电脑端入口
  • 金融网站建设内容上海优化公司排行榜
  • wordpress 搜索框 404百度搜索关键词排名优化技术
  • 做网站干嘛成功营销十大经典案例
  • 梅河口市建设局网站免费seo快速收录工具
  • 济南网站设计制作要多久百度关键词指数排行
  • 为什么只有中国做网站需要备案怎么进行推广
  • 用flask做的网站企业网站设计优化公司
  • 海外设计网站建设四川百度推广排名查询
  • 自己做的网站图片不显示google chrome谷歌浏览器
  • 自己做鞋子网站谷歌广告投放教程
  • 做思维导图好看的网站合肥网站制作公司
  • 重庆工程建设信息网站白山网络推广
  • 设计公司的网站如何做seo优化
  • 做装修网站seo的收费标准
  • 做视频网站 版权怎么解决windows优化大师最新版本
  • 做网站鼎盛网站后台管理系统
  • 朋友 合同 网站制作独立站seo优化
  • 网站seo优化包括哪些方面淘宝店铺怎么推广和引流
  • 做网站用c语言可以吗建立免费个人网站
  • python编程软件安装教程重庆seo推广服务
  • 做编程的 网站百度近日收录查询
  • 做网站流量优化都是什么企业管理软件排名
  • 定制网站建设设计公司推广运营怎么做
  • 做效果图的兼职网站seo高效优化
  • 网站开发后台 amp长沙网站优化培训
  • 网站后台做链接深圳推广系统
  • 深圳公司注销流程seo优化行业