我听说PermGC中存在字符串对象池,当执行字符串实习时,它首先检查池以查看是否存在等效的字符串对象,如果它不存在,则创建一个并返回对该字符串的引用。汇集实例。
但这是我的第一个问题。
我认为该对象是在堆上创建的,尤其是在年轻一代中。如果它在几个垃圾收集期间幸存下来,它会移动到旧一代。任何人都可以解释字符串对象如何进入Perm GC中存在的池?
第二个问题:
String s =“test”; s =“test1”;
如果我将“test1”重新分配给引用并继续使用“test1”,是否意味着“test”(在年轻一代上创建)将被垃圾收集?
第三个问题: 字符串对象池如何与运行时常量池相关?感谢。
答案 0 :(得分:2)
是什么让你认为实习字符串首先流向年轻一代? String#intern()
方法是本机方法。对于实现来说,将其直接移入permgen当然是非常可能的。
第二个问题:如果没有对该"test"
字符串实例的其他引用,则它有资格进行垃圾回收。如果它被实习,同样的故事。即使是不再具有任何活动引用的实习字符串也可以进行垃圾回收。但是,在较旧的JVM中可能不是这种情况。我想这可能是特定于实现的。
至于第三个问题,我不知道。我所知道的是源代码中的字符串文字放在同一个池中。如果要从源构造一个等于String常量的字符串,然后实习它,则返回用于表示常量的实例。可以把它想象成已经立即实习的字符串文字。
编辑:再次阅读你的最初几句话,我想我看到了混乱的原因。当你在String上调用intern()
,并且池中没有相同的String时,那么它不会首先构造一个等效的String。它只是将您调用intern()
的实例移动到池而不是返回新的引用。 That's how it's stated in the JavaDoc
答案 1 :(得分:0)
在两种情况下,字符串会进入实习池:
池被组织为一个表,一旦字符串被实现,如果该值尚未存在,则将其添加到池中,否则将使用对现有条目的引用。
你的情况下的“测试”应该去游泳池,而不是去年轻的空间,无论如何也要在那里执行不再引用的字符串的清理(我不能说它是否是用于相同的GC过程的一部分)堆也不是这种行为是标准的)