什么时候字符串会在java中被垃圾收集

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18406703/
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-08-12 01:20:10  来源:igfitidea点击:

When will a string be garbage collected in java

javastringgarbage-collection

提问by Victor

In Java, when an object has got no live reference, it is eligible for garbage collection. Now in case of a string, this is not the case because string will go into the string pool and JVM will keep the object alive for resuse. So that means a string once created will 'never' be garbage collected?

在 Java 中,当一个对象没有活动引用时,它就有资格进行垃圾回收。现在在字符串的情况下,情况并非如此,因为字符串将进入字符串池,JVM 将使对象保持活动状态以供重用。那么这意味着一旦创建的字符串将“永远不会”被垃圾收集?

采纳答案by Stephen C

Now in case of a string, this is not the case because string will go into the string pool and JVM will keep the object alive for resuse. So that means a string once created will 'never' be garbage collected?

现在在字符串的情况下,情况并非如此,因为字符串将进入字符串池,JVM 将使对象保持活动状态以供重用。那么这意味着一旦创建的字符串将“永远不会”被垃圾收集?

First, it is onlystring literals(see notes) that get automatically interned / added to the string pool. Stringobjects that are created by an application at runtime are not interned ... unless your application explicitly calls String.intern().

首先,只有字符串文字(见注释)会自动插入/添加到字符串池中。 String由应用程序在运行时创建的对象不会被实习......除非您的应用程序显式调用String.intern().

Second, in fact the rules for garbage collecting objects in the string pool are the same as for other Stringobjects: indeed all objects. They will be garbage collected if they ever become unreachable.

其次,实际上字符串池中对象的垃圾回收规则与其他String对象相同:实际上是所有对象。如果它们变得无法访问,它们将被垃圾收集。

In practice, the Stringobjects that correspond to string literals typicallydo not become candidates for garbage collection. This is because there is an implicitreference to the Stringobject in the code of every method that uses the literal. This means that the Stringis reachable for as long as the method could be executed.

实际上,String对应于字符串文字的对象通常不会成为垃圾回收的候选对象。这是因为在使用字面量的每个方法的代码中都有一个对对象的隐式引用String。这意味着String只要该方法可以执行,就可以访问。

However, this is not alwaysthe case. If a string literal was defined in a class that was dynamically loaded (e.g. using Class.forName(...)), then it is possible to arrange that the class is unloaded. If that happens, then the Stringobject corresponding to the literal maythen be unreachable, and may ultimately be GC'ed.

然而,情况并非总是如此。如果在动态加载(例如使用Class.forName(...))的类中定义了字符串文字,则可以安排卸载该类。如果发生这种情况,则String对应于文字的对象可能无法访问,并且最终可能会被 GC 处理。

See also: When and how are classes garbage collected in Java?

另请参阅:Java 中的类垃圾收集何时以及如何进行?



Notes:

笔记:

  1. A string literal (JLS 3.10.5) is a string that appears in Java source code; e.g.

      "abc"            // string literal
      new String(...)  // not a string literal
    
  2. A string produced by evaluation of (compile-time) constant expression (JLS 15.28) may also be interned.

      "abc" + 123      // this is a constant expression
    
  3. Strictly speaking, not all String literals are interned. If a String literal only appears in the source code as a sub-expression of a constant expression, then the literal may not appear in the ".class" file in any form. Such a literal won't be interned because it won't exist at runtime.

  1. 字符串文字 ( JLS 3.10.5) 是出现在 Java 源代码中的字符串;例如

      "abc"            // string literal
      new String(...)  // not a string literal
    
  2. 通过(编译时)常量表达式 ( JLS 15.28)的评估产生的字符串也可以被实习。

      "abc" + 123      // this is a constant expression
    
  3. 严格来说,并不是所有的 String 字面量都是实习生的。如果字符串字面量仅作为常量表达式的子表达式出现在源代码中,则该字面量可能不会以任何形式出现在“.class”文件。这样的文字不会被实习,因为它在运行时不存在。

回答by SLaks

You are correct; strings in the intern pool will never be GC'd.

你是对的; 实习池中的字符串永远不会被 GC 处理。

However, most strings on not interned.
String literalsare interned, and strings passed to String.intern()are interned, but all other strings are not interned and can be GC'd normally.

但是,大多数字符串都没有被实习。
字符串字面量是实习的,传递给的字符串String.intern()是实习的,但所有其他字符串都不是实习的,可以正常进行 GC。

回答by Tharsanan

String objects which are in the string pool will not be garbage collected. Other String objects will be garbage collected if you don't have reference to it in your program execution.

字符串池中的字符串对象不会被垃圾回收。如果您在程序执行中没有引用它,其他 String 对象将被垃圾收集。

You may ask which string objects goes to string pool.Objects in the string pool are either:

您可能会问哪些字符串对象进入字符串池。字符串池中的对象是:

  • Compile time literals (e.g.String s1 = "123";)

  • Interned String objects in the runtime (e.g. String s2 = new String("test").intern();)

  • 编译时文字(例如String s1 = "123";

  • 运行时中的实习字符串对象(例如String s2 = new String("test").intern();

Both s1and s2reference a string object in the string pool.

双方s1s2在字符串池中引用的String对象。

Any objects which are created at run time and not interned will act as a normal object and reside in heap memory. These objects can be garbage collected.

任何在运行时创建且未驻留的对象都将充当普通对象并驻留在堆内存中。这些对象可以被垃圾回收。

An example of this would be: String s3 = s1 + s2;

这方面的一个例子是: String s3 = s1 + s2;

Here, s3references a string object which resides in heap memory alongside other objects (not in the String pool).

在这里,s3引用一个字符串对象,该对象与其他对象一起驻留在堆内存中(不在字符串池中)。