java - 字符串范围 : regular heap vs pool

标签 java string

我知道字符串池是如何工作的。也就是说:

void doSomething1(){
 System.out.println("This string is now added to the string pool and will stay there even after this method returns");
}

void doSomething2(){
 String msg = new String("This string is now added to the string pool and will stay there even after this method returns");

 System.out.println(msg);
}

doSomething2 是否优于 doSomething1。鉴于某些字符串被重用的可能性非常低,是否应该鼓励这样做。我看到的问题是在情况 1 中,即使不再使用该字符串,它也会长时间保留在范围内。

最佳答案

Is doSomething2 better than doSomething1.

没有。

Should this be encouraged, given that some Strings have a very low chance of being reused.

没有。

The problem I see is in case 1, the string stays in scope for extended period even when it is not used again.

我认为您误解了这里发生的事情。

字符串 "This string ... returns" 是一个字符串文字,当类包含这些方法时,它被添加到字符串池一次且仅一次已加载。

  • doSomething1() 不会将字符串添加到字符串池中。相反,它使用字符串池中已有的字符串(我上面提到的字符串)。

  • doSomething2() 方法对存在于字符串池中的原始字符串进行了全新复制。您是正确的,doSomething2() 创建的副本不在字符串池中。但是,您一开始就创建副本并没有获得任何有用的东西。最好只使用原始字符串。

最后需要注意的是,类加载时创建的字符串池中的String会一直留在那里,直到类被卸载(如果被卸载),或者直到应用程序结束。您对此无能为力……您应该对此无能为力。

(这种情况类似于 C 或 C++ 中的字符串文字所发生的情况。C/C++ 字符串文字表示为程序初始化常量区域中的字节序列。它将在程序运行期间一直存在,并且您无法或应该做任何事情来尝试回收空间。)


But for the sake of understanding and completeness: Here is a big string which is only going to be used once and if I can keep it short scoped, why put it in the pool?

因为 JVM 不会尝试(并且在一般情况下不能)确定常量只会被使用一次。这种分析很困难,而且不值得付出努力。

对于任何合理大小的字符串文字,不太可能在持续时间内它在池中产生任何实际差异。如果字符串文字足够大或足够多以至于它确实有所作为,那么它们应该替换为从类路径或其他地方的资源中读取的字符串。由程序员进行此调用...而不是 JVM。

关于java - 字符串范围 : regular heap vs pool,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18139996/

相关文章:

java - JTextField 在使用 FlowLayout 时显示为狭缝...请解释

java - 玩家和敌人之间的碰撞不起作用

java - Last-Modified 与 ETag http

string - 无法在多重分配中将 []byte 分配给 z(字符串类型)

Java 字符串拆分结果

Javascript函数将文本分割成两个长度相同的字符串

java - Maven:验证目标不会在自动化测试中打开浏览器

java - Spring引导安全: Issue while showing login page in Angular 8

java - 将 "\"更改为 "/"

MySQL 查询按字母顺序 A-Z 但 "AA"之后是 "Z"