java - 字符串实习如何在 Java 7+ 中工作?

标签 java string jvm heap-memory string-interning

<分区>

所以,我意识到我要问的问题与一个一次又一次被打死的话题有关,然而,即使在阅读了我能找到的所有答案和文档之后,我仍然很友善对字符串实习感到困惑。也许是因为我对JVM 缺乏了解;也许是由于 Java 7 中引入的更改贬低了许多上述答案和文档。无论哪种方式,我都被卡住了,我希望有人能帮助我更清楚地理解这个概念......

String a = "text";
String b = new String("text");

在上面的示例中,我了解到将创建两个 String 对象。我还了解到,内存中将只有一个包含序列 't'、'e'、'x' 和 't' 的字符数组。

但是,每个字符串对象实际存储在内存中的什么位置?

如果我没看错的话:变量 a 的引用将存储在常量池中,而 b 的引用将存储在堆,对吧?

如果是这样的话,我对实习生池如何维护实习生字符串感到困惑。它是否跟踪常量池中定义的字符串以及那些已从堆中手动驻留(调用 .intern())的字符串? JVM 是否创建常量池中定义的字符串对象并将它们加载到实习生池中?我对这一切如何运作感到困惑...

再次抱歉,我提出了如此令人困惑/愚蠢的问题,只是我对 JVM 的结构和内部工作原理还比较陌生,其中的很多内容让我头晕目眩。谢谢!

最佳答案

java中有一个叫做String Memory Pool的东西,当你声明的时候:

String str1="abc";

它进入那个内存池而不是堆上。但是当你写:

String str2=new String("abc");

它在堆上创建一个完整的对象,如果你再次写:

String str3 = "abc"; 

它不会在池中创建更多的对象,它会检查池,如果这个文字已经存在,它将分配给它。但是写:

String str4 = new String("abc");

将再次在堆上创建一个新对象

重点是:

一个新对象总是会在堆上创建,次数与你继续写入的次数一样多:

new String("abc");

但是如果你继续直接分配字符串而不使用关键字 new,它只会从内存池中引用(或者如果内存池中不存在则创建)

intern() 方法查找字符串是否存在于内存池中,如果不存在,则将其添加到内存池并返回对它的引用。所以在使用这个方法之后,你的字符串引用没有指向堆上的任何对象,它指向字符串内存池中的一个对象(另外,请注意内存池只包含唯一的字符串)。

关于java - 字符串实习如何在 Java 7+ 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27210280/

相关文章:

java - 使用类名调用不同类的方法

java - JVM 禁用特定类或方法的内联

java - 当分析 session 结束时,类检测是否会被删除?

c# - 将单词转换为字符数组

java - 同一程序在两个不同的 JVM 中

java - SimpleXML - 反序列化时如何忽略类属性

java - 在 Java 中重写 toString() 时遇到问题

java - 为什么两个看似相同的 hashmap 在被 gson 序列化时有不同的行为?

python - 按单词匹配更改,而不是按字符

python - 简单的python程序问题