对象的堆与字符串常量池内存表示
Heap vs String Constant Pool memory representation for Object
在 Java 7 或更低版本中,如果使用以下语法创建字符串
String s1=new String("abc");
根据this link,每当我们创建一个字符串对象时,都会创建两个对象,一个在堆区,一个在字符串常量池,字符串对象引用总是指向堆区对象如下所示。
----------------------------------------------
| Heap | String Constant Pool |
|---------------------|-----------------------
| | |
| "abc" | "abc" |
| ^ | |
| | | |
| s1 | |
如果我们创建另一个具有与
相同值的 String 对象,内存表示将是什么
String s2=new String("abc");
这会在堆中创建另一个具有相同值的对象吗?
或者它只会将引用 String 常量池的对象创建到堆中?
----------------------------------------------
| Heap | String Constant Pool |
|---------------------|-----------------------
| | |
| "abc" "abc" | "abc" |
| ^ ^ | |
| | | | |
| s1 s2 | |
正如 Andy Turner 所说,new
运算符总是生成一个新实例。由JLS保证。
唯一的小问题是在某些情况下(例如,如果在某些 JVM 版本中启用了逃逸分析),new
运算符可能会在堆栈而不是堆上分配对象。
在 Java 7 或更低版本中,如果使用以下语法创建字符串
String s1=new String("abc");
根据this link,每当我们创建一个字符串对象时,都会创建两个对象,一个在堆区,一个在字符串常量池,字符串对象引用总是指向堆区对象如下所示。
----------------------------------------------
| Heap | String Constant Pool |
|---------------------|-----------------------
| | |
| "abc" | "abc" |
| ^ | |
| | | |
| s1 | |
如果我们创建另一个具有与
String s2=new String("abc");
这会在堆中创建另一个具有相同值的对象吗?
或者它只会将引用 String 常量池的对象创建到堆中?
----------------------------------------------
| Heap | String Constant Pool |
|---------------------|-----------------------
| | |
| "abc" "abc" | "abc" |
| ^ ^ | |
| | | | |
| s1 s2 | |
正如 Andy Turner 所说,new
运算符总是生成一个新实例。由JLS保证。
唯一的小问题是在某些情况下(例如,如果在某些 JVM 版本中启用了逃逸分析),new
运算符可能会在堆栈而不是堆上分配对象。