String相关面试题

一、String的基本特性:

具体可以查看网址查看变更具体信息:

http://openjdk.java.net/jeps/254

a、String 的不可变性:

 eg(1):

 (2)

 原有字符串常量池里的"abc" 不变,只是在常量池里新创建了一个"abcdef"

(3)

 b、字符串常量池里不能存储相同内容的字符串、

底层实现:

二、String的内存分配:

内存位置发生改变:

 StringTable为什么要调整?

(1)permSize默认比较小,

(2)永久代垃圾回收频率比较低

三、String的基本操作:

 因为上面字符串常量池已经有"1",所以还是2304

四、字符串拼接操作:

eg(1):

常量与常量的拼接结果一定在常量池中。

上述代码反编译后:

ldc 是加载常量池中的"abc"

eg(2):

 只要拼接的时候有一个变量,结果就在堆中,拼接原理是StringBuilder.

 变量拼接原理的底层操作:

字节码如下:

 通过如上字节码 s1+s2d 执行细节如下:(变量s是我临时定义的)

StrinBuilder s = newStringBuilder();

s.append("a");

s.append("b");

s.toString();----》约等于 new String("ab"); 只不过在常量池里没有"ab";

补充:在jdk5.0之后使用的是StringBuilder,在jdk5.0之前所使用的是StringBuffer。

五、intern()的使用:

String.intern()源码如下:

 

 如何将变量s 指向字符串常量池的数据呢:

方式一:String s = "junjie";//定义字面量的方式。

方式二:使用intern() 方法。

六、 new String("ab") 到底创建了几个对象:

答案:两个;

字节码如下:

ldc:加载常量池里的"ab", 堆空间 一个,所以两个。

拓展:new String("a")+new String("b") 创建了几个对象:

字节码如下:

对象一:new StringBuilder();

对象二:new String("a");

对象三:常量池里的"a"

对象四:new String("b")

对象五:常量池里的"b"

 注意:StringBuilder.toString()方法:

字节码如下:

发现常量池里并没有创建对象,只是new String("ab");

对象六:new String("ab")

 七、intern()方法的使用:jdk6 vs jdk7/8

例子:

 jdk6 字符串常量池在方法区中,而jdk7/8 字符串常量池在堆中。

s3.intern() 在jdk6中,因为String s3 = new String("1")+new String ("1") 并没有在字符串常量池中创建“11”,而是在s3.intern() 之后在字符串常量池中创建了“11”,所以为fasle。

s3.intern() 在jdk7/8中,因为String s3 = new String("1")+new String ("1") 并没有在字符串常量池中创建“11”, jdk7/8将字符串常量池由方法区移动到了堆内存中,因为堆内存中已经创建了 "11" 对象,在s3.intern()之后,由于为了节省堆内存,只是在常量池中创建了新的引用指向了堆空间中的“11” 对象,所以为true。

总结:

注意:jdk7/8 是把堆内存对象的引用复制一份到常量池中,返回常量池中引用对象的地址。

八、intern()空间效率测试:

对于程序中大量存在的字符串,尤其其中存在很多重复字符串时,使用intern() 可以节省内存空间。

九、StringTable的垃圾回收:

JVM添加如下参数:

-Xms15m -Xmx15m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails

PrintStringTableStatistics:统计字符串常量池的信息。

字符串常量池的统计信息:

 

字符串常量池的统计信息:

循环十万次呢:

字符串常量池的统计信息:

发现不够10万次,进行垃圾回收:

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值