【问题标题】:Total Number of String objects created in the process?进程中创建的字符串对象总数?
【发布时间】:2013-06-26 23:53:51
【问题描述】:
String str1="JAVA";
String str2="JAVA";
String str3=new String("JAVA");
String str4=new String("JAVA").intern();

将创建 2 个对象。 str1 和 str2 引用相同的对象,因为字符串字面量池概念,str3 指向新对象,因为使用 new 运算符,str4 指向相同的对象,str1 和 str2 指向相同的对象,因为 @987654328 @ 方法在字符串池中检查具有相同值的字符串。

str1=str2=str3=str4=null;

一个对象将有资格进行 GC。也就是通过String str3=new String("JAVA")创建的对象。第一个 String 对象始终可以通过存储在字符串字面量池中的引用访问。

我的解释正确吗?

【问题讨论】:

    标签: java string object


    【解决方案1】:

    进程中创建的String对象总数?

    三个:实习池中通过文字创建的一个和您通过new String 创建的两个。

    一个对象将有资格进行 GC。

    在非常特殊情况下,我数了两个,甚至可能全部三个:

    1. 你在这一行创建的那个:

      String str3=new String("JAVA");
      

      (因为您后来将str3 设置为null)。

    2. 你在这一行临时创建的那个:

      String str4=new String("JAVA").intern();
      

      该行创建一个新的String 对象,在其上调用intern,然后保存对池中字符串的引用。所以理论上,它会创建一个String 对象,可以立即用于GC。 (JVM 可能足够聪明,不会那样做,但这就是理论。)

    3. 可能,最终,在适当的条件下,甚至是实习生池中的字符串。与普遍的看法相反,实习池中的字符串可用于垃圾收集,正如我们从the answer to this other question 中看到的那样。仅仅因为它们在 permgen (unless you're using Oracle's JVM 7 or later) 中并不意味着它们不是 GC'd,因为 the permgen is GC'd too。所以问题就变成了:何时或如何在代码中不再引用字符串 literal?我不知道答案,但我认为一个合理的假设 是:何时以及是否从内存中卸载使用它的类。根据this other answer,只有当类 及其类加载器 都被卸载时才会发生这种情况(即使那样也可能不会发生)。如果类是由系统类加载器加载的(正常情况),那么它可能永远不会被卸载。

    所以几乎可以肯定只有两个(上面的 #1 和 #2),但研究 #3 也很有趣。

    【讨论】:

    • 它们都设置为null。由于所有引用都明确设置为null,GC 不应该全部收集它们吗?
    • 哦..没注意到 :) 喝咖啡的时间。
    • 我听说实习字符串也可以收藏——它们不会永远在烫发宝石中
    • @dantuch:在最近的一个版本中,是的。我忘了那是 6 还是 7。编辑: 是 7。
    • @TJCrowder 我们不应该将“Java”等同于“OpenJDK HotSpot JVM”,关于 PermGen 和字符串常量的详细信息仅与后者有关(甚至可能与它的所有执行模式无关) . Java 规范中对此没有任何规定。
    猜你喜欢
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 2011-08-31
    • 1970-01-01
    • 2015-09-08
    • 2014-11-22
    相关资源
    最近更新 更多