Lok*_*esh 21 java string garbage-collection
我正在阅读垃圾收集,当我搜索字符串文字垃圾收集时,我的搜索结果令人困惑.
我需要澄清以下几点:
如果在编译时将字符串定义为文字[例如:String str = "java"
]那么它是否会被垃圾收集?
如果使用实习方法[例如:String str = new String("java").intern()
]那么它会被垃圾收集吗?它也将与第1点中的字符串文字区别对待.
有些地方提到只有在String
卸载类时才会对文字进行垃圾收集?它是否有意义,因为我认为String
不会卸载课程.
Ste*_*n C 19
如果在编译时将字符串定义为文字[例如:
String str = "java";
]那么它是否会被垃圾收集?
可能不是.代码对象将包含String
对表示文字的对象的一个或多个引用.因此,只要代码对象可以访问,String
对象就是.
代码对象可能无法访问,但只有在它们被动态加载时...才会破坏它们的类加载器.
如果我使用实习方法[例如:
String str = new String("java").intern()
]那么它会被垃圾收集吗?
intern
调用返回的对象将是表示"java"
字符串文字的同一对象.("java"
文字是在类加载时间实现的.当你String
在代码片段中实习新构造的对象时,它将查找并返回先前实例化的"java"
字符串.)
但是,与字符串文字不相同的实习字符串一旦无法访问就可以进行垃圾回收.PermGen空间是在所有最近的HotSpot JVM上进行垃圾收集的.(在Java 8之前......完全丢弃了PermGen.)
它也将与第1点中的字符串文字区别对待.
不...因为它与字符串文字是同一个对象.
事实上,一旦你理解了正在发生的事情,很明显字符串文字也没有特别对待.它只是"可达性"规则的应用......
有些地方提到只有在
String
卸载类时才会对文字进行垃圾收集?它是否有意义,因为我不认为String
该类将被卸载.
你是对的.这没有意义.那些说不正确的消息来源.(如果您发布了一个URL,以便我们可以阅读他们为自己说的内容,将会很有帮助...)
jac*_*obm 10
在正常情况下,字符串文字和类都被分配到JVM的永久代("PermGen")中,并且通常不会被收集.被拦截的字符串(例如mystring.intern()
)存储在String
permgen中的类所拥有的内存池中,曾经的情况是,激进的实习可能会导致空间泄漏,因为字符串池本身持有对每个字符串的引用,即使没有其他字符串也是如此参考文献存在.显然这已不再适用,至少从JDK 1.6开始(例如,参见此处).
有关permgen的更多信息,这是对该主题的一个不错的概述.(注意:该链接指向与产品关联的博客.我与博客,公司或产品没有任何关联,但博客条目很有用,与产品无关. )