在创建String时,我已经阅读了很多关于内存分配的相互矛盾的文章.
有些文章说新的运算符在堆中创建一个String,而String literal是在String Pool [Heap]中创建的,而有些人则说新运算符在堆中创建一个对象而另一个对象在String池中创建.
为了分析这个,我编写了下面的程序,它打印了String char数组和String对象的哈希码:
import java.lang.reflect.Field;
public class StringAnalysis {
private int showInternalCharArrayHashCode(String s)
throws SecurityException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException {
final Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
return value.get(s).hashCode();
}
public void printStringAnalysis(String s) throws SecurityException,
IllegalArgumentException, NoSuchFieldException,
IllegalAccessException {
System.out.println(showInternalCharArrayHashCode(s));
System.out.println(System.identityHashCode(s));
}
public static void main(String args[]) throws SecurityException,
IllegalArgumentException, NoSuchFieldException,
IllegalAccessException, InterruptedException {
StringAnalysis sa = new StringAnalysis();
String s1 = new String("myTestString");
String s2 = new String("myTestString");
String s3 = s1.intern();
String s4 = "myTestString";
System.out.println("Analyse s1");
sa.printStringAnalysis(s1);
System.out.println("Analyse s2");
sa.printStringAnalysis(s2);
System.out.println("Analyse s3");
sa.printStringAnalysis(s3);
System.out.println("Analyse s4");
sa.printStringAnalysis(s4);
}
}
该程序打印以下输出:
Analyse s1
1569228633
778966024
Analyse s2
1569228633
1021653256
Analyse s3
1569228633
1794515827
Analyse s4
1569228633
1794515827
从这个输出中可以清楚地看出,无论String如何创建,如果字符串具有相同的值,则它们共享相同的char数组.
现在我的问题是这个chararray存储在哪里,是存储在堆中还是存在于permgen?另外,我想了解如何在堆内存地址和permgen内存地址之间进行区分.
我有一个很大的问题,如果它存储在permgen,因为它会占用我珍贵的有限的permgen空间.如果char数组没有存储在permgen中而是存储在堆中,那么它是否意味着String文字也使用堆空间[这是我从未读过的东西].