今天看了一些关于Java String的一些文章,同时自己也思考了一下,在此记录一下。如果有写的不对的地方,欢迎指正。
我们使用java的字符串比较常见的有两种方式。
1. String a = “abc“;
2. String a = new String("abc");
第一种方式应该会先检查"abc"这个字符串是不是在一个字符串的常量池中,如果有的话,那么jvm就会返回一个引用给a,只要是以第一种方式这样使用"abc”字符串的变量,他们都会指向相同的对象。
String str1 = "abc";
String str2 = "abc";
str1 == str2 会返回true, str1和str2的定义可以在一个类中,也可以不在。
第二种方式应该会在heap上创建一个String对象, 然后返回这个对象的引用给a。
String str1 = "abc";
String str2 = new String("abc");
String str3 = new String("abc");
str1 == str2 会返回false
str2 == str3 会返回false
str1 == str2.intern() 会返回true, 因为intern方法会把"abc”加入到常量池中(如果不存在的话), 然后返回指向常量池的引用
对于第二种方式,本人有一些疑问,根据java String定义,String会有一个char[] 来存放字符串的值,但是jvm真的会对每个new的具有相同内容的String对象保存一份吗?要是这样的话,不是会很消耗heap的存储吗?
public class Test {
public static void main(String[] args) {
String[] strs = new String[1024000];
for(int i = 0; i < 1024000; i++) {
strs[i] = newString("1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
"111111111111111111111111" + "111111111111111111111111");
}
}
}
localhost:bin edric$ java -XX:MaxPermSize=5m -Xmx10m -XX:-PrintGC -XX:HeapDumpPath=/tmp -XX:+HeapDumpOnOutOfMemoryError -XX:-UseGCOverheadLimit Test
java.lang.OutOfMemoryError: Java heap space
Dumping heap to /tmp/java_pid3248.hprof ...
Heap dump file created [17668098 bytes in 0.273 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Test.main(Test.java:7)
212117 instances of class java.lang.String
经过分析,上边程序创建的String对象确实存在heap中,而且导致了outofmemory错误
所以说jvm确实会对相同内容的string对象保存不同的副本。