jvm中字符串存放在哪里?字符串常量池存放的又是什么?

最近在学习jvm只是点时遇见了一个问题,就是字符串常量池中存放的是什么?

下面我会基于我的理解来讲述一下我的观点。

首先说结论:字符串堆中的字符串常量池存放字符串和字符串引用

为什么这样理解?

        我们先看下图

这是常量池也叫class常量池,字符串常量池因为其使用频率高的特殊性,jvm为其划分了一块特殊区域

所以字符串常量池包含的内容和class常量池的内容有所区别,我们看下图

字符串常量池中存放直接引用

那么什么是符号引用什么是直接引用呢?

        符号引用:符号引用就是一个类中(当然不仅是类,还包括类的其他部分,比如方法,字段等)引入了其他的类,可是JVM并不知道引入的其他类在哪里,所以就用唯一符号来代替,等到类加载器去解析的时候,就通过符号引用找到那个引用类的地址,这个地址也就是直接引用

        直接引用:直接引用是和虚拟机的布局相关的,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,那引用的目标必定已经被加载入内存中了。

        直接引用可以是
(1)直接指向目标的指针(比如,指向“类型”【Class对象】、类变量、类方法的直接引用可能是指向方法区的指针)
(2)相对偏移量(比如,指向实例变量、实例方法的直接引用都是偏移量)
(3)一个能间接定位到目标的句柄

为什么说存放引字符串字符串引用

        首先就我们必须得清楚,字符串对象在jvm中存放的位置:字符串常量池堆内存

        简要概述:

        String a = "a";时字符串对象存在于字符串常量池,此时String类提供一个API:intern()这个API可以手动将一个字符串对象的值转移到字符串常量池中,它是一个native方法,

Hotspot JVM里字符串常量池它的逻辑在注释里写得很清楚:①.如果常量池中有这个字符串常量,就直接返回,否则将该字符串对象的值存入常量池,再返回

        ①.那么此时我们能确定字符串对象存在于常量池中

        String b = new String("a"),这个代码大家不陌生,面试中也常问到这段代码创建了几个对象。那么他是如何运行的呢?

        ②.如果字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用。否则,若该字符串对象已经存在于 Java 堆中,则将堆中对此对象的引用添加到字符串常量池中,然后返回该引用;如果堆中不存在,则在池中创建该字符串并返回其引用

        ②.那么此时我们能确定字符串引用存在于常量池中

        

 


版权声明:本文为Kami__Sama原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>