本问题已经有最佳答案,请猛点这里访问。
我想更深入地了解字符串池。 请帮助我访问包含Java实现的源类文件。
问题更多与查找字符串池的源代码或实现有关,以更深入地研究此概念,以进一步了解其中的一些未知或难以捉摸的事物。 这样,如果我们有一个应用程序创建了很多文字和字符串对象,我们可以更有效地利用字符串,或者想出其他方法来实现我们自己的垃圾回收。
通过查看实际代码,您将无法更好地理解字符串池。 基本上,这是一种哈希图 具体来说,JVM知道此特殊映射仍然支持所包含字符串的垃圾回收。 如果您了解这些原理,则无需查看代码。 另一方面,如果您不理解,该代码将无济于事。
@霍尔格 我确实了解hashmap的工作。 通过查看实际的实现,我到目前为止正在寻找更多"未读"的东西。
令您失望的是我很抱歉,但是Java String-Pool不是实际的Java类,而是在JVM中实现的某个地方,即它以C ++代码编写。
如果查看String类的源代码(从头到尾),您会发现intern()方法是本机的。
您将必须通过一些JVM代码来获取更多信息。
编辑:
可以在此处找到一些实现(C ++标头,C ++实现)。 搜索StringTable。
Edit2:正如Holger在评论中指出的那样,这并不是JVM实现的硬性要求。 因此,可能有一个JVM以不同的方式实现字符串池,例如 使用实际的Java类。 尽管所有常用的JVM我都知道可以在JVM C ++代码中实现它。
感谢您的信息。是的,在源代码中,该方法是本机的。您能否提供一个链接,我可以从中下载本机源代码。
我不确定它是用C还是C ++编写的^^但实际上它是C ++,因此我将对其进行修复。
@ Ankit_ceo2,您应该可以在这里下载download.java.net/openjdk/jdk7
@ Ankit_ceo2我用在哪里可以找到的一些信息更新了我的答案
好吧,有一些用Java编写的JVM。但是,字符串池是HotSpot的私有内部优化细节,因此其他JVM可能不会拥有它。
@Jrg W Mittag:规范要求用??相同的实例表示相等的字符串文字,也就是在相等的实例上调用String.intern()返回的相同的实例。因此,每个JVM必须具有某种类型的字符串池或等效字符串池。只有它的实际工作方式才取决于实现。
@Holger:有趣。我在整个JLS和JVMS中搜索了" pool"一词,我所得到的都是关于JVMS中常量池的命中以及对JLS POOL会议录中发表的Java Generics Wildcards论文的引用。
@Jrg W Mittag:不要卡在"水池"一词上。参见JLS 3.10.5。字符串文字:"此外,字符串文字始终引用String类的相同实例。这是因为使用" String.intern"方法对字符串文字(或更一般而言,是作为常量表达式的值的字符串(15.28))进行"内联",以便共享唯一的实例。如前所述,这取决于JVM如何实现,但是从语义上讲,所有字符串文字总是形成某种类型的池。
5.1中的JVM规范也反映了这一点。运行时常量池:Java编程语言要求相同的字符串文字(即,包含相同代码点序列的文字)必须引用类String(JLS 3.10.5)的相同实例。另外,如果在任何字符串上调用方法String.intern,则结果是同一个类实例的reference,如果该字符串以文字形式出现,则将返回该类实例。
@Holger:好的,所以从根本上说,这个答案是错误的,因为它声称没有实现字符串池的Java代码。
@Jrg W Mittag:Java代码处理特定类文件的字符串常量,而不处理由JVM实现的全局池。类的常量池与JVM的全局字符串池交互,但是它们仍然是不同的池。除此之外,此答案涉及Oracle著名的参考JVM,但不一定适用于世界上所有的JVM。
@Holger:啊,谢谢你抓住了这个。这看起来很有希望:kenai.com/projects/maxine/sources/maxine/content/
@Holger感谢您的评论。您说得对,我已将其包含在答案中。
@JrgWMittag Maxine是一个研究VM,不再开发。除此之外,它是用Java编写的,因此您在此处引用的字符串池仍然是VM的一部分,而不是语言/运行时的一部分。
您可以阅读本文:字面上的字符串
When a .java file is compiled into a .class file, any String literals
are noted in a special way, just as all constants are. When a class is
loaded (note that loading happens prior to initialization), the JVM
goes through the code for the class and looks for String literals.
When it finds one, it checks to see if an equivalent String is already
referenced from the heap. If not, it creates a String instance on the
heap and stores a reference to that object in the constant table. Once
a reference is made to that String object, any references to that
String literal throughout your program are simply replaced with the
reference to the object referenced from the String Literal Pool.
So, in the example shown above, there would be only one entry in the
String Literal Pool, which would refer to a String object that
contained the word"someString". Both of the local variables, one and
two, would be assigned a reference to that single String object. You
can see that this is true by looking at the output of the above
program. While the equals() method checks to see if the String objects
contain the same data ("someString"), the == operator, when used on
objects, checks for referential equality - that means that it will
return true if and only if the two reference variables refer to the
exact same object. In such a case, the references are equal. From the
above output, you can see that the local variables, one and two, not
only refer to Strings that contain the same data, they refer to the
same object.
质量引用质量很差:存在许多错误,并且实现方式随着时间的推移而发生了变化。例如,许多工作是由编译器完成的,而不是由JVM完成的,并且JVM检查.class文件中的常量表,而不是字节码。