java字符串运行原理(StringTable)

例题:

public static void main(String args[]) {
		String s1="a";
		String s2="b";
		String s3="a"+"b";//编译器会进行优化
		String s4=s1+s2; //new了一个StringBuilder方法, 对应着  new StringBuilder().append(s1).append(s2).toString()[toString()方法创建了一个新的变量]
		String s5="ab";
		String s6=s4.intern();//会进行入池操作,然后返回Stringtable中相应元素的内容

		//问
		System.out.println(s3==s4);
		System.out.println(s3==s5);
		System.out.println(s3==s6);
		System.out.println(s4==s6);
		
		String x2=new String("c")+new String("d");
		String x1="cd";
		x2.intern();
		
		//问
		System.out.println(x1==x2);
	}

结果:

false
true
true
false
false

原理解释:

  • 常量池最初存在于编译后的字节码文件中,当加载字节码文件的时候,常量池会被加载到运行时常量池中,但是此时,运行时常量池的常量,还未变成java对象,等到运行到对应的语句时(用到该对象的时候),再加载成对应的java的对象。同时,准备好一块空间(Stringtable),以此时的java 对象为键,在Stringtable中寻找是否有相同的对象。若没有,则放入stringtable中。所以Stringtable每中个常量都是唯一的

  • 同时,javac在编译期间会进行优化。常量的结果在编译期间会进行拼接,因为结果已经确定了。但是变量不会在编译期间管理(因为变量的值可能会变)。会通过堆内存存储。Stringtable存储的为常量对象。变量对象,存储在堆内存中。
  • intern(),将在堆上开辟的对象存到Stringtable中。如果有,则不会放入:如果没有,则将对象放入到Stringtable中。并返回Stringtable的对象。

以上只是jdk1.8的intern(),在1.8以下,如果Stringtable中没有该对象。会把此对象复制一份,放入Stringtable中,并把Stringtable的对象返回

  • Stringtable数据结构相当于一个hashtable,长度固定并且无法扩容。当1.6环境及以下,Stringtable在方法区中;而1.7及以上,Stringtable在堆内存中。

原因?

永久代的垃圾回收效率会很慢(在FULL GC时,才会进行垃圾回收,而Stringtable的更新十分频繁,所以不合适在永久代中,放在堆中可实现Minor  GC即可回收)

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值