java 字符串文字的垃圾收集

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15324143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 19:14:32  来源:igfitidea点击:

Garbage collection of String literals

javastringgarbage-collection

提问by Lokesh

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 [e.g: String str = "java"] then will it be garbage collected?

  2. If use intern method [e.g: String str = new String("java").intern()] then will it be garbage collected? Also will it be treated differently from String literal in point 1.

  3. Some places it is mentioned that literals will be garbage collected only when Stringclass will be unloaded? Does it make sense because I don't think Stringclass will ever be unloaded.

  1. 如果一个字符串在编译时被定义为文字 [eg: String str = "java"] 那么它会被垃圾收集吗?

  2. 如果使用实习生方法 [eg: String str = new String("java").intern()] 那么它会被垃圾收集吗?在第 1 点中,它的处理方式与 String 文字也不同。

  3. 有些地方提到只有在String卸载类时才会对文字进行垃圾收集?这是否有意义,因为我认为String课程永远不会被卸载。

采纳答案by Stephen C

If a string is defined as literal at compile time [e.g: String str = "java";] then will it be garbage collected?

如果一个字符串在编译时被定义为文字 [eg: String str = "java";] 那么它会被垃圾收集吗?

Probably not. The code objects will contain one or more references to the Stringobjects that represent the literals. So as long as the code objects are reachable, the Stringobjects will be to.

可能不是。代码对象将包含String对表示文字的对象的一个或多个引用。所以只要代码对象可达,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 [e.g: String str = new String("java").intern()] then will it be garbage collected?

如果我使用 intern 方法 [eg: String str = new String("java").intern()] 那么它会被垃圾收集吗?

The object returned by the interncall will be the same object that represents the "java"string literal. (The "java"literal is interned at class loading time. When you then intern the newly constructed Stringobject in your code snippet, it will lookup and return the previously interned "java"string.)

intern调用返回的对象将与表示"java"字符串文字的对象相同。("java"文字在类加载时被实习。当你String在你的代码片段中实习新构造的对象时,它将查找并返回以前实习的"java"字符串。)

However, interned strings that are not identical with string literals canbe garbage collected once they become unreachable. The PermGen space isgarbage collected on all recent HotSpot JVMs. (Prior to Java 8 ... which drops PermGen entirely.)

但是,与字符串文字不相同的实习字符串一旦变得不可访问,就会被垃圾收集。PermGen 空间在所有最近的 HotSpot JVM 上进行垃圾收集的。(在 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 Stringclass will be unloaded? Does it make sense because I don't think the Stringclass will ever be unloaded.

有些地方提到只有在String卸载类时才会对文字进行垃圾收集?这是否有意义,因为我认为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 会很有帮助,这样我们就可以自己阅读他们在说什么......)

回答by jacobm

Under normal circumstances, string literals and classes are all allocated into the JVM's permanent generation ("PermGen"), and usually won't ever be collected. Strings that are interned (e.g. mystring.intern()) are stored in a memory pool owned by the Stringclass 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. Apparently this is no longer true, at least as of JDK 1.6 (see, e.g., here).

在正常情况下,字符串字面量和类都分配到 JVM 的永久代(“PermGen”)中,通常不会被收集。被拘留的字符串(例如mystring.intern())存储在所拥有的内存池String在PermGen的类,而它曾经的情况是,即使没有其他积极的实习可能导致内存泄露,因为字符串池本身持有的每一个字符串的引用存在参考文献。显然这不再正确,至少从 JDK 1.6 开始(参见,例如,here)。

For more on permgen, thisis a decent overview of the topic. (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.)

有关 permgen 的更多信息,是对该主题的一个不错的概述。(注意:该链接指向与产品关联的博客。我与博客、公司或产品没有任何关联,但博客条目很有用,与产品没有太大关系。 )

回答by fredrik

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

回答by AmitG

intern()method checks the availability of the object in String pool. 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()方法检查字符串池中对象的可用性。如果对象/文字可用,则将返回它的引用。如果池中不存在文字,则将对象加载到永久区域(字符串池)中,然后返回对它的引用。我们必须intern()明智地使用方法。