JVM学习笔记之StringTable

一、String的特性

               字符串常量池是不会存储相同的字符串的。

        

1.为什么jdk9要将String底层改为byte[]?

       因为大多数String对象仅仅包含一个拉丁文,只需要一个字节就可以存储,导致一般的空间没有被使用到,节省了空间,减少了GC的触发次数,提高了系统的性能。

       但是处理中文时,(LATIN1编码集支持的字符有限,其中就不支持中文字符,因此才保留了UTF16兜底)。

2.设置字符串常量池的大小

        

二、String的内存分配

        

1.StringTable为什么要从永久代调整到堆中?

      ①永久代内存较小 ②永久代垃圾回收频率较低

三、字符串的拼接

         

1.示例代码

/**
     * s1 + s2 的执行细节:
     *     ①StringBuilder sb = new StringBuilder();
     *     ②sb.append("a")
     *     ③sb.append("b")
     *     ④sb.toString();  --> 约等于 new String("ab")
     */
    @Test
    public void test(){
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2;
        System.out.println(s3 == s4);//false
    }

2.StringBuilder的append方法效率比字符串之间拼接高

       在开发中:如果基本确定要添加的字符串长度不超过某个限定值highLevel的情况下,建议使用构造器:StringBuilder sb = new StringBuilder(highLevel);

四、intern()的使用

1.public native String intern();

2.典型题目示例

public class StringInternTest {
    public static void main(String[] args) {

        String s = new String("1");
        //s = s.intern();     //这样s = s2才为true
        s.intern(); //调用此方法前“1”就已经存在与常量池中了,存在就会返回一个指向常量池的值,但是这里s没有接收该值,所以为false
        String s2 = "1";
        System.out.println(s == s2);//false

        String s3 = new String("a") + new String("b");//调用toString,在字符串常量池中不会生成"ab"
        //执行完上行代码后,字符串常量池中不存在“ab”
        s3.intern();        //jdk6:在字符串常量池中生成“ab”,s4->字符串常量池“ab”,s3在堆空间, 所以为false
                            //jdk7/8:由于堆空间已经存在“ab”,这时字符串常量池会保存堆空间“ab”的地址
        String s4 = "ab";   //s4->字符串常量池“ab”->s3,所以为true
        System.out.println(s3 == s4);//jdk6:false  jdk7/8:true
    }
}

3.总结String和intern()的使用

     

4.使用intern()测试效率:空间上

     对于程序中大量存在的字符串,尤其其中存在很多重复的字符串时,使用intern()可以节省很多内存空间。(由于堆中已经有的字符串,常量池中会将该对象的引用地址复制放入其中,而不会去新建一个字符串)

五、G1中String的去重操作

        

        

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值