String在虚拟机的实现

1、String在虚拟机的实现

不变性

可以提高多线程访问的性能,因为对象不可变因此对于所有线程都是只读的,多线程访问时不加同步也不会产生数据的不一致,故减少了系统开销;

针对常量池的优化

当两个String对象拥有相同的值时只引用常量池中的同一个拷贝,可以大幅度节省内存空间;

类的final定义

String类在系统中不可能有任何子类,这是对系统安全性的保护;

2、String的内存泄漏

内存泄漏:由于不再使用的对象占据内存不被释放导致可用内存不断减小最终导致内存泄漏;

在JDK1.6中,String主要由三部分组成,代表字符数组的value、偏移量offset、长度count;

如果字符串value数组包含100个字符,而count长度只有一个字节,那么这个String十几行只有一个字符却占据了至少100个字节,那么剩余的99个就属于泄露的部分,他们不会被使用不会被释放却长期占用内存;,知道字符串本身被回收;

JDK1.6的substring():
String在虚拟机的实现

新生成的String简单地使用相同的value引用,只是修改了offset和count,一旦原始字符串被回收,value中多余的部分就造成了空间浪费;

在1.7版本的substring中,不再复用原String的value,而是将实际需要的部分做了复制;

3、String常量池的位置

1.6以及之前的版本是在永久区,在之后的版本被移到了堆中进行管理;

String.intern()获得在常量池中的字符串引用,如果常量池中没有该常量字符串,会将该字符串加入常量池;

虽然String.intern()返回值永远等于字符串常量,但存在一种情况:一次intern调用之后该字符串在某一个时刻被回收,之后再次调用intern,字面量相同的字符串重新被加入常量池,但是引用位置已经改变;

rn()返回值永远等于字符串常量,但存在一种情况:一次intern调用之后该字符串在某一个时刻被回收,之后再次调用intern,字面量相同的字符串重新被加入常量池,但是引用位置已经改变;