JVM内存模型讲解
类的初始化过程、类的实例化过程
1.JVM初始化步骤
2.类加载时机
3.类加载过程
4.类初始化时机
5.类的初始化过程
6.类的实例化
JVM常量池、字符串常量池概念
JVM常量池、Class常量池、运行时常量池、字符串常量池:
StringTable字符串常量池
StringTable字符串常量池【对于intern()讲解的到位】
StringTable特性
- JVM常量池中的字符串仅是字符,第一次使用时才变为对象
- 利用串池机制,避免重复创建字符串
- 字符串变量拼接原理是StringBuilder(1.8)
- 字符串常量拼接原理是编译器优化
- StringTable在1.6中存放在永久代,在1.8中存放在堆空间
- intern方法主动将串池中没有的字符串对象放入串池
- 1.8中:将字符串对象尝试放入到串池中,如果串池中没有该字符串对象,则放入成功;如果有该字符串对象,则放入失败。无论是否放入成功,都会返回串池中的字符串对象。如果调用intern方法成功,堆内存与串池中的字符串对象是同一个对象;如果失败,则不是同一个对象
- 1.6中:将字符串对象尝试放入到串池中,如果串池中有该字符串对象就不放入;如果没有就复制一个放进去(本身不放入)。无论放入是否成功,都会返回串池中的字符串对象。无论调用intern方法成功与否,串池中的字符串对象和堆内存中的字符串对象都不是同一个对象
补充
String str = new String("a") + new String("b");
将上述代码反编译,生成反编译结果,部分的代码如下:
9: new #5 // class java/lang/StringBuilder
12: dup
13: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
16: aload_1
17: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: aload_2
21: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
27: astore #4
这行代码实际操作是,创建了一个StringBuilder对象,然后一路append,最后toString。而toString其实是又重新 new 了一个 String 对象,然后把对象给 str,此时并没有在字符串常量池中添加常量