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

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

So, I realize the questions I'm about to ask relate to a topic that has been beaten to death time and time again, however, even after reading all of the answers and documentation I could find, I'm still kind of confused about string interning. Perhaps it's due to my lack of understanding for the JVM; perhaps it's due to the changes introduced in Java 7 depreciating many of the aforementioned answers and documentation. Either way, I'm stuck, and I'm hoping someone can help me understand the concept a bit more clearly...

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

在上面的例子中,我知道会创建两个 String 对象.我也知道内存中只有一个包含序列 't'、'e'、'x' 和 't' 的 char 数组.

In the above example, I understand that two String objects will be created. I also understand that there will be only one char array containing the sequence 't', 'e', 'x', and 't' in memory.

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

However, where in memory are each of the string objects actually stored?

如果我读过的内容我没看错:变量 a 的所指对象将存储在常量池中,而 b 的所指对象将存储在堆,对吧?

If what I've read I've read correctly: the referent of variable a will be stored in the constant pool whereas the referent of b will be stored in the heap, right?

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

If that be the case, I'm confused as to how the intern pool maintains interned strings. Does it keep track of the Strings defined in the constant pool and those that have been manually interned (invoked .intern()) from the heap? Does the JVM create the string objects defined in the constant pool and load them into the intern pool? I'm confused as to how it all works...

再次,很抱歉提出如此令人困惑/愚蠢的问题,只是我对 JVM 的结构和内部工作方式相对较新,其中很多都让我头晕目眩.谢谢!

Again, sorry for asking such confusing/asinine questions, it's just that I'm relatively new to the structure and inner-workings of the JVM and a lot of it has left my head spinning. Thanks!

推荐答案

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

There's a thing called String Memory Pool in java, when you declare:

String str1="abc";

它进入那个内存池而不是堆.但是当你写的时候:

It goes to that memory pool and not on the heap. But when you write:

String str2=new String("abc");

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

It creates a full fledged object on the heap, If you again write:

String str3 = "abc"; 

它不会在池中创建更多对象,它会检查池是否已经存在这个字面量,它将分配给它.但写作:

It won't create any more object on the pool, it will check the pool if this literal already exists it will assign that to it. But writing:

String str4 = new String("abc");

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

will again create a new object on the heap

关键是:

一个新对象总是会在你不断写的时候在堆上创建多少次:

A new object will always be created on the heap as many times as you keep writing:

new String("abc");

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

But if you keep assigning the Strings directly without using the keyword new, it will just get referenced from the memory pool (or get created if not present in the memory pool)

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

intern() method finds if the string is present in the memory pool if it is not it adds it to the memory pool and returns a reference to it. so after using this method the String reference of yours is not pointing to any object on the heap, it is pointing to an object in the String Memory Pool (Also, note that the memory pool only contains unique strings).

相关文章