实战JAVA虚拟机 JVM故障诊断与性能优化(七)--->无处不在的字符串:String在虚拟机中的实现

  String类型虽然不是基本类型,但是也享有了和基本数据类型一样的待遇。

1.String对象的特点:

  a.不变性

    指String对象一旦生成,则不能再对它进行改变,由于不变性,一些看起来像是修改的操作,实际上都是依靠产生新的字符串实现的,比如,String.substring()、String.concat()方法,它们都没有修改原来的字符串,而是产生了一个新的字符串,这一点是非常值得注意的。如果需要一个可以修改的字符串,那么需要使用StringBuffer,StringBuilder对象。

  b.针对常量池的优化

    指当两个String对象拥有相同的值时,它们只引用常量池中同一个拷贝。

String str1 = new String("aaa");
String str2 = new String("aaa");
// intern() 获取引用地址
System.out.println(str1 == str2); // false
System.out.println(str1 == str2.intern()); // false
System.out.println("aaa" == str1.intern()); // true

  c.类的final定义

    作为final类的String对象在系统总不可能有任何子类,这是系统安全性的保护。

    

2.有关String的内存泄漏

  所谓内存泄漏,就是由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,它并不是说物理内存消失了,而是指由于不再使用的对象占据内存不被释放,而导致可用内存不断减少,最终有可能导致内存溢出。

  在jdk1.6中,java.lang.String 主要由3部分组成:

      

  在jdk1.6中,使用String.substring()方法只是将offset,count的值进行调整,value[] 数组的内容不变,当String对象很长时,substring()对导致内存溢出

  在jdk1.7中已经更改为:

  public static int[] copyOfRange(int[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        int[] copy = new int[newLength];
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));
        return copy;
    }

 3.有关String常量池的位置

  jdk1.6之前属于永久区一部分,但是在jdk1.7之后,它就被移到了堆中进行管理。

  

原文地址:https://www.cnblogs.com/kaishi/p/7491293.html