【发布时间】:2010-02-04 18:30:05
【问题描述】:
我对字符串有一些疑问
它们是生活在堆还是字符串池上?
如果在堆上,如果任何活动线程都无法访问它们,那么它们将被垃圾回收。
如果在字符串池中,那么它们将如何被删除或移除,因为我们知道垃圾收集只发生在堆上。
【问题讨论】:
标签: java
我对字符串有一些疑问
它们是生活在堆还是字符串池上?
如果在堆上,如果任何活动线程都无法访问它们,那么它们将被垃圾回收。
如果在字符串池中,那么它们将如何被删除或移除,因为我们知道垃圾收集只发生在堆上。
【问题讨论】:
标签: java
String s = new String("abc");
s 引用的字符串对象将在堆上,而字符串字面量“abc”将在字符串池中。字符串池中的对象不会被垃圾回收。它们可以在程序的生命周期内重复使用,以提高性能。
【讨论】:
它们都存储在堆中,但intern()ed 字符串(包括源中的字符串文字)是从String 类的池中引用 .
如果它们在源代码中以文字形式出现,包括常量字符串表达式(例如 "a" + "b"),那么它们也将被 Class 引用,这通常意味着只要进程运行它们就会持续存在.
编辑:
当您在代码中对字符串调用 intern() 时,它也会添加到此池中,但由于它使用弱引用,因此如果不再使用该字符串可以仍然被垃圾回收。
另请参阅: interned Strings : Java Glossary
引用那篇文章:
在这个 HashMap 中注册的字符串集合有时被称为字符串池。但是,它们是普通的对象,并且像其他任何对象一样都存在于堆上(也许以一种优化的方式,因为实习字符串往往寿命很长)。
【讨论】:
String 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");
【讨论】: