Java教程之String类的底层原理和版本演变

1 String类的底层演变

JDK8以及之前的版本在这里插入图片描述
JDK9以及之后的版本在这里插入图片描述

	JDK8的字符串存储在char类型的数组里面,在java中,一个char类型占两个字节。但是很多时候,一个字符只需要一个字节就可存储,比如各种字母什么的,两个字节存储势必会浪费空间,JDK9的一个优化就在这,内存的优化,所以JDK9之后字符串改成byte类型数组进行存储。

    private final byte coder;    
	在JDK9的String类中,新增了一个属性coder,它是一个编码格式的标识,使用LATIN1还是UTF16,这个是在String生成的时候自动确定的,如果字符串中都是能用LATIN1编码表示,那coder的值就是0,否则就是UTF16编码,coder的值就是1。
        
	可以看到JDK9在这方面的优化,在较多情况下不包含那些奇奇怪怪的字符的时候,足以应付,而这个空间却小了1byte,实现了String空间的压缩。

2 String常量池的演变

2.1 StringTable变化
StringString Pool是一个固定大小的 Hashtable。
    
	在jdk6中,StringTable的长度固定为1009。
    如果放进 String PoolString非常多,就会造成Hash冲突严重,从而导致链表会很长,而链表长了后直接会造成的影响就是当调用 intern() 时性能会大幅下降。
    
    从jdk7起,StringTable的长度默认值是60013。
    
    使用-XX:StringTableSize可设置StringTable的长度。     
	在jdk8之前,对StringTableSize的设置没有最小限制。
	jdk8开始,StringTable可设置的最小值是1009。
        

验证:
	通过 jps 命令查看进程号
    使用 jinfo -flag StringTableSize 进程号 查看StringTable大小    
2.2 内存位置变化
Java6及以前,字符串常量池存放在永久代。
    
Java7开始,字符串常量池的位置调整到Java堆内。
所有的字符串都保存在堆(Heap)中,和其他普通对象一样,这样在进行调优应用时仅需要调整堆大小就可以了。

官网说明

https://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html#jdk7changes

在这里插入图片描述

JDK6环境下测试:

/*
    jdk6中,修改JVM内存大小:
    -XX:PermSize=6m -XX:MaxPermSize=6m -Xms6m -Xmx6m
 */
public class StringTableTest {
   
    public static void main(String[] args) {
   
        Set<String> set = new HashSet<String>();

        int i=0;
        while (true){
   
            set.add(String.valueOf(i++).intern());
        }
    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值