【问题标题】:strings and memory allocation in java?java中的字符串和内存分配?
【发布时间】:2011-10-22 05:41:06
【问题描述】:

我一直想知道的一件事,如果我有这样的方法:

String replaceStuff (String plainText) {
        return plainText.replaceAll("&", "&");
}

它会一直为“&”和“&”创建新的 String 对象,这些对象被 GC 销毁,然后在下一次调用时重新创建? 例如。 理论上做这样的事情会更好吗

final String A ="&";
final String AMP ="&";

    String replaceStuff (String plainText) {
            return plainText.replaceAll(A, AMP);
    }

我认为这可能是一个比现实生活中的问题更理论的问题,我只是好奇内存管理在这方面是如何处理的。

【问题讨论】:

    标签: java memory


    【解决方案1】:

    没有。字符串文字是实习的。即使您使用其他地方的相等文字(或其他常量),您仍然会引用同一个对象:

    Object x = "hello";
    Object y = "he" + "llo";
    
    System.out.println(x == y); // Guaranteed to print true.
    

    编辑:JLS 在第 3.10.5 节中保证这一点

    使用String.intern 方法,字符串字面量——或更一般地,作为常量表达式值的字符串(第 15.28 节)——被“内部”以共享唯一实例。

    第 15.28 节显示 + 运算符被包含为一个可以从其他两个常量生成新常量的操作。

    【讨论】:

    • Object y = "hello" 有保证,但对"he" + "llo" 的编译器优化是否也有保证? (我是在问,不是挑战 :-))
    • @Sean:这也是有保证的。它在 JLS 的第 3.10.5 节的this part 中:“字符串文字,或者更一般地说,作为常量表达式值的字符串(第 15.28 节)-是“实习的”[...]”
    • @Sean:保证;我已添加参考。
    • @Joachim:是的,我添加了相同的参考 :)
    【解决方案2】:

    不,它们是字面量,因此会自动嵌入到常量池中。

    您每次创建新字符串的唯一方法是:

    String replaceStuff (String plainText) {
       return plainText.replaceAll(new String("&"), new String("&"));
    }
    

    【讨论】:

      【解决方案3】:

      GC 处理字符串的方式与处理普通对象的方式略有不同。 例如如果

      字符串 a = "aaa"; 字符串 a1 = "aaa";

      现在 a 和 a1 都将指向内存中相同的 String 值,直到任何值发生变化。因此内存中只有 1 个对象。

      此外,如果我们将 'a' 和 'a1' 更改为指向任何其他字符串,则值“aaa”仍然留在字符串池中,如果需要,稍后将由 JVM 使用。该字符串不是 GC'd

      【讨论】:

      • 其实它们不是被GC处理的不同,而是在构建过程中。
      • 值得注意的是,这是针对编译时字符串constants。以其他方式创建的字符串不会自动被实习。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 2021-07-27
      • 2022-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多