JVM---运行时数据区-堆-字符串常量池


/**
     *      
     *
     *          基本特性
     *              字符串,使用一对 "" 表示;
     *
     *              ***不可变
     *                  1、堆中字符串常量池 不会存储相同内容的字符串
     *                  eg:
     *                  private static void testStringConstantPool1() {
     *
     *                      String s = "a";
     *                      String ss = "a";
     *
     *                      System.out.println(s == ss); // true
     *                      System.out.println(s); // a
     *                      System.out.println(ss); // a
     *
     *                  }
     *
     *                  2、当变量指向新的字符串时,堆中字符串常量池 旧的字符串不会被移除
     *                  eg:
     *                  private static void testStringConstantPool2() {
     *                      String s = "a";
     *                      String ss = "a";
     *                      ss = "hello";
     *
     *                      System.out.println(s == ss); // false
     *                      System.out.println(s); // a
     *                      System.out.println(ss); // hello
     *                  }
     *
     *                  3、当对旧有 堆中字符串常量池 的字符串进行操作时,旧有字符串不会被移除
     *                  eg:
     *                  private static void testStringConstantPool3() {
     *                      String s = "a";
     *                      String ss = "a";
     *                      String sss = "a";
     *                      ss += "hello";
     *                      sss = sss.replace("a", "c");
     *
     *                      System.out.println(s); // a
     *                      System.out.println(ss); // ahello
     *                      System.out.println(sss); // c
     *                  }
     *
     *          <字符串常量池本质>
     *              字符串常量池 是一个固定大小的Hashtable,默认大小长度是1009;如果字符串常量池放任的String非常多,会造成hash冲突,导致链表很长,调用String.intern时性能大幅下降;
     *
     *              字符串常量池大小:
     *                  JDK6中,字符串常量池是固定的1009;
     *                  JDK7中,字符串常量池 默认是60013,1009是最小值;
     *                  JDK8中,字符串常量池 1009是最小值;
     *
     *                  查看当前进程的大小:
     *                      jps
     *                      jinfo -flag StringTableSize 进程ID
     *
     *                  设置 字符串常量池的长度:
     *                      -XX:StringTableSize
     *
     *          
     *              在Java语言中有 8种基本数据类型和String;为了使它们在运行过程中速度更快,更节省内存,都提供了 常量池的概念;
     *
     *              String类型的常量池使用方式:
     *                  a,直接使用 "" 声明出来的String对象 会直接存储在 常量池;
     *                      "a";
     *                  b,使用String的intern();
     *
     *              存放位置:
     *                  JDK6及之前,字符串常量池 存放于 堆的永久代;
     *                  JDK7,字符串常量池 在堆中(非永久代);
     *                  JDK8及之后,字符串常量池 在堆中(无永久代);
     *
     *              字符串常量池移到 非永久代的原因:
     *                  jdk 7 将 字符串常量池 移至堆中,因为 永久代的回收效率很低,只有FullGC 的时候 才会 回收 永久代;
     *                  在 开发中 会创建大量的字符串,回收效率太低,导致 永久代 空间不足;
     */
JVM