我正在努力理解字符串池是如何工作的。我经历了很多网站,最后我现在更加困惑了。让我在这里放下我的疑虑。有人帮助我理解它们。
1)字符串池在哪里?在堆中还是在方法区域?
2)String s = "Hello world";
- 这就足以创建一个string.Since字符串是不可变的,一旦创建了字符串不能更改,那么创建字符串的需要是什么
String s = new String(“Hello World”)
?
虽然它强制JVM在堆中而不是String池中创建一个新的String对象。但是对于新的String对象强制JVM的需求是什么?
3)字符串何时以及如何收集垃圾?
提前致谢。
答案 0 :(得分:4)
除了保证:
之外,在Java中如何管理字符串的实际实现不应该是重要的。这些是Strings的规则......
过去(这将随Java8而改变),String.intern()
和字符串常量(String x = "hi"
)被分配在内存模型的PermGen空间中。
因此,它们具有不同的GC机制,即使您有大量的可用堆空间(PermGen通常小于128MB),如果使用String.intern()
也可能会耗尽内存。
使用new String(....)
分配的字符串在常规堆上,并且具有标准GC机制。
至于为什么你/我们使用new String ("...")
创建字符串的新实例,我只能想到一个只有这样做才有意义的地方,那就是有人想要使用结果对象作为同步锁。这在调试时可能有意义.....但没有多大意义。您必须使用'new',这样您就不会无意中使用与其他代码相同的String对象进行同步。
在一般的Java编码实践中,我通常没有看到人们使用new String ("....")
。现实情况是,人们在大多数情况下只使用字符串连接运算符等。但是,这并不意味着做new String(...)
当我查看String的源代码时,我发现代码在很大程度上依赖于String是不可变的。所以,例如,new String(new String(“hi”));只创建一个char数组,并在两个String实例中共享它。 (无论如何,内部实例将是GC'd。)
答案 1 :(得分:0)
1.String pool不是STACK,也不是HEAP!这是方法区!
字符串池属于常量池。因为我们都知道,CONSTANT是一个无法改变的值,给定一个恒定池的目的是加快程序的速度。在您的类文件中,例如int a = 10, String b = "123450"
被视为字符串(您可以在方法中更改它们)。加载类时,JVM会将它们放在一个数组中进行维护。并将此数组放在名为String Pool的METHOD区域中。
2.当您创建String对象时,您可以执行以下操作:
String str1 = new String("abc")
和Stirng str2 = "abc";
。它们看起来一样,但JVM以不同的方式处理它们。对于第一个,JVM将在HEAP中创建String对象。并将对象返回给用户。但是对于第二个,JVM将使用String的equals()
方法检查String Pool,以检查String池是否存在String的对象。如果是,则将String的对象返回给用户,并且不会重新创建String的新对象。如果String池没有String对象,JVM将在HEAP中创建一个新对象并返回给用户,同时JVM将把它放入String池中。
String str1 = new String("abc"); //jvm creates a String object in Heap.
//jvm can not find "abc" in String pool
//Create a String object in heap,and put it in strings pool
//Now heap has two string object.
Stirng str2 = "abc";
if(str1 == str2){
System.out.println("str1 == str2");
}else{
System.out.println("str1 != str2");
}
//Print result is str1 != str2, because they are different objects in heap
String str3 = "abc";
//Now,jvm realizes String Pool already had “abc” object,because “abc”equals “abc”
if(str2 == str3){
System.out.println("str2 == str3");
}else{
System.out.println("str2 != str3");
}
//Print result is str2 == str3
String str1 = new String("abc");
str1 = str1.intern();
Stirng str2 = "abc";
if(str1 == str2){
System.out.println("str1 == str2");
}else{
System.out.println("str1 != str2");
} //Print: str1 == str2
答案 2 :(得分:0)
字符串池就像一个具有String
常量的存储桶。
例如: -
Object a = new Object();
Object b = new Object();
它将在Heap中创建两个新对象。
但是,
String s1 = "abc";
String s2 = "abc";
它只会在String
池中创建一个对象,因为它们是常量。