简体   繁体   English

字符串文字的垃圾收集

[英]Garbage collection of String literals

I am reading about Garbage collection and i am getting confusing search results when i search for String literal garbage collections. 我正在阅读有关垃圾回收的信息,当我搜索字符串文字垃圾回收时,搜索结果令人困惑。

I need clarification on following points: 我需要澄清以下几点:

  1. If a string is defined as literal at compile time [eg: String str = "java" ] then will it be garbage collected? 如果在编译时将字符串定义为文字字符串(例如: String str = "java" ],那么是否将其垃圾回收?

  2. If use intern method [eg: String str = new String("java").intern() ] then will it be garbage collected? 如果使用内部方法[例如: String str = new String("java").intern() ],那么会被垃圾回收吗? Also will it be treated differently from String literal in point 1. 在第1点中,它也将与String文字区别对待。

  3. Some places it is mentioned that literals will be garbage collected only when String class will be unloaded? 有人提到只有在卸载String类时才会对文字进行垃圾回收吗? Does it make sense because I don't think String class will ever be unloaded. 是否有道理,因为我认为String类永远不会被卸载。

If a string is defined as literal at compile time [eg: String str = "java"; 如果在编译时将字符串定义为文字[例如: String str = "java"; ] then will it be garbage collected? ]然后会被垃圾收集吗?

Probably not. 可能不是。 The code objects will contain one or more references to the String objects that represent the literals. 代码对象将包含一个或多个对表示文字的String对象的引用。 So as long as the code objects are reachable, the String objects will be to. 因此,只要代码对象可访问, String对象就可以到达。

It is possible for code objects to become unreachable, but only if they were dynamically loaded ... and their classloader is destroyed. 代码对象可能无法访问,但前提是它们是动态加载的……并且其类加载器已销毁。

If I use the intern method [eg: String str = new String("java").intern() ] then will it be garbage collected? 如果我使用内部方法[例如: String str = new String("java").intern() ],那么它会被垃圾回收吗?

The object returned by the intern call will be the same object that represents the "java" string literal. intern调用返回的对象将是与表示"java"字符串文字的对象相同的对象。 (The "java" literal is interned at class loading time. When you then intern the newly constructed String object in your code snippet, it will lookup and return the previously interned "java" string.) "java"文字在类加载时进行了实习。然后,在代码片段中实习新构造的String对象时,它将查找并返回先前实习的"java"字符串。)

However, interned strings that are not identical with string literals can be garbage collected once they become unreachable. 但是,与字符串文字不相同的实习字符串一旦变得不可访问,便可以进行垃圾回收。 The PermGen space is garbage collected on all recent HotSpot JVMs. PermGen的空间收集所有近期热点的JVM的垃圾。 (Prior to Java 8 ... which drops PermGen entirely.) (在Java 8之前……这会完全删除PermGen。)

Also will it be treated differently from string literal in point 1. 在第1点中,它也将与字符串文字区别对待。

No ... because it is the same object as the string literal. 否...,因为它与字符串文字是同一对象。

And indeed, once you understand what is going on, it is clear that string literals are not treated specially either. 确实,一旦您了解了所发生的情况,很明显,字符串文字也不会被特别对待。 It is just an application of the "reachability" rule ... 这只是“可达性”规则的应用...

Some places it is mentioned that literals will be garbage collected only when String class will be unloaded? 有人提到只有在卸载String类时才会对文字进行垃圾回收吗? Does it make sense because I don't think the String class will ever be unloaded. 是否有道理,因为我认为String类永远不会被卸载。

You are right. 你是对的。 It doesn't make sense. 这没有道理。 The sources that said that are incorrect. 表示不正确的消息来源。 (It would be helpful if you posted a URL so that we can read what they are saying for ourselves ...) (如果您发布一个URL,这将很有帮助,以便我们可以阅读他们自己说的话...)

Under normal circumstances, string literals and classes are all allocated into the JVM's permanent generation ("PermGen"), and usually won't ever be collected. 在正常情况下,字符串文字和类都分配到JVM的永久代(“ PermGen”)中,通常不会收集。 Strings that are interned (eg mystring.intern() ) are stored in a memory pool owned by the String class in permgen, and it was once the case that aggressive interning could cause a space leak because the string pool itself held a reference to every string, even if no other references existed. 被实习的字符串(例如, mystring.intern() )存储在permgen中的String类拥有的内存池中,并且曾经有一次积极的实习可能导致空间泄漏,因为字符串池本身持有对每个对象的引用。字符串,即使不存在其他引用也是如此。 Apparently this is no longer true, at least as of JDK 1.6 (see, eg, here ). 显然,至少从JDK 1.6起,这种情况不再成立(例如,参见here )。

For more on permgen, this is a decent overview of the topic. 有关permgen的更多信息, 是该主题的不错概述。 (Note: that link goes to a blog associated with a product. I don't have any association with the blog, the company, or the product, but the blog entry is useful and doesn't have much to do with the product.) (请注意:该链接指向与产品关联的博客。我与博客,公司或产品没有任何关联,但是博客条目非常有用,与产品没有太大关系。 )

  1. The literal string will remain in memory as long as the program is in memory. 只要程序在内存中,文字字符串就会保留在内存中。
  2. str will be garbage collected, but the literal it is created from will not. str将被垃圾回收,但是不会从中创建它的文字。
  3. That makes perfect sense, since the string class is unloaded when the program is unloaded. 这是很合理的,因为在卸载程序时将卸载字符串类。

intern() method checks the availability of the object in String pool. intern()方法检查字符串池中对象的可用性。 If the object/literal is available then reference of it will be returned. 如果对象/文字可用,则将返回其引用。 If the literal is not there in the pool then object is loaded in the perm area (String pool) and then reference to it will be return. 如果池中没有文字,则将对象加载到烫发区域(字符串池)中,然后返回对其的引用。 We have to use intern() method judiciously. 我们必须明智地使用intern()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM