/**
*
*
* 基本特性
* 字符串,使用一对 "" 表示;
*
* ***不可变
* 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 的时候 才会 回收 永久代;
* 在 开发中 会创建大量的字符串,回收效率太低,导致 永久代 空间不足;
*/