垃圾回收和字符串

5

我对字符串有一些疑问

它们是存储在堆上还是字符串池中?

如果存储在堆上,那么只要没有任何活动线程引用它们,它们就会被垃圾回收。

如果存储在字符串池中,那么它们将如何被删除或移除,因为我们知道垃圾回收只发生在堆上。

3个回答

8
String s = new String("abc");

s所引用的字符串对象将位于堆上,而字符串字面值“abc”将位于字符串池中。字符串池中的对象不会被垃圾回收。它们在程序的生命周期内被重复使用,以提高性能。


如果您正在引用类定义的一部分——_常量池_,那么您是可以卸载常量池的,前提是您可以卸载该类(通常需要取消对类加载器及其已加载类的所有引用)。这比您通常编写的程序更加困难,但Tomcat可以做到。 - Edwin Buck

5
它们都存储在堆中,但使用intern()的字符串(包括源代码中的字符串文字)从String类中的池中引用。如果它们作为源代码中的文字出现,包括常量字符串表达式(例如"a" + "b"),则它们也将从它们所在的Class中引用,这通常意味着它们将持续到进程运行结束。
编辑:当您在代码中调用intern()时,字符串也会添加到此池中,但由于它使用弱引用,因此如果不再使用该字符串,则可以进行垃圾回收。
另请参见: interned Strings : Java Glossary 引用自该文章:
HashMap中注册的字符串集合有时称为字符串池。但是,它们是普通对象,与任何其他对象一样存在于堆上(也许以优化的方式存在,因为国际化字符串往往具有长寿命)。

1

字符串Alex进入文字池,只要进程运行(或Web应用程序保持加载状态),它就会一直留在那里,如finnw所说,并且永远不会被垃圾回收。字符串name2不为“Alex”分配内存,而是从文字池中重复使用。

PS:文字池也在堆上。

对于字符串John,创建了两个对象,引用名称为name3和name4,这些对象可以被垃圾回收。

String name = "Alex";
String name2 = "Alex";

String name3 = new String("John");
String name4 = new String("John");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接