Java 常量池

article/2025/9/24 0:18:24

常量池分为 Class 常量池常量池、运行时常量池、字符串常量池。

1、 Class 常量池常量池(静态常量池)

Java 文件被编译成 Class 文件,Class 文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项就是 Class 常量池,Class 常量池是当 Class 文件被 Java 虚拟机加载进来后存放各种字面量 (Literal)和符号引用

字面量相当于 Java 语言层面常量的概念,如文本字符串、基础数据、声明为 final 的常量等;符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:类和接口的全限定名、字段名称描述符、方法名称描述符。类的加载过程中的链接部分的解析步骤就是把符号引用替换为直接引用,即把那些描述符(名字)替换为能直接定位到字段、方法的引用或句柄(地址)。
在这里插入图片描述

2、运行时常量池

运行时常量池是方法区的一部分。运行时常量池是当 Class 文件被加载到内存后,Java虚拟机会将 Class 文件常量池里的内容转移到运行时常量池里,即编译期间生成的字面量、符号引用(运行时常量池也是每个类都有一个)。一般来说,除了保存 Class 文件中描述的符号引用外,还会把翻译出来的直接引用也存储到运行时常量池中。
运行时常量池相对于 Class 文件常量池的另外一个重要特征是具备动态性,Java 语言并不要求常量一定只有编译期才能产生,也就是并非预置入 Class 文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中

(1)方法区的 Class 文件信息,Class 常量池和运行时常量池的三者关系:
在这里插入图片描述
(2)运行时常量池在 JDK1.6、JDK1.7 和 JDK 8 的变化

1)在 JDK1.7 之前运行时常量池存放在方法区,逻辑包含字符串常量池,存放字面量和符号引用,此时 hotspot 虚拟机对方法区的实现为永久代。
2)在 JDK1.7 中字符串常量池被从方法区拿到了堆中,这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区,也就是hotspot中的永久代。
3)在 JDK1.8 中,hotspot 移除了永久代用元空间(Metaspace)取而代之,这时候字符串常量池还在堆,运行时常量池还在方法区,只不过方法区的实现从永久代变成了元空间(Metaspace)

3、字符串常量池

字符串常量池又称为字符串池,全局字符串池,英文也叫 String Pool。JVM 为了提升性能和减少内存开销,避免字符串的重复创建,其维护了一块特殊的内存空间,这就是字符串常量池。字符串常量池由 String 类私有的维护。
全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的字符串值存到 string pool 中(记住:string pool中存的是字符串值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的。)

(1)字符串常量池的位置变化

1) 在 JDK7 之前字符串常量池是在永久代里边的,但是在 JDK7 中,把字符串常量池移到了堆里边
在这里插入图片描述
2) 在 JDK8 中,把字符串常量池仍在堆里边在这里插入图片描述

(2)两种创建字符串对象不同方式的比较

1)采用字面值的方式创建字符串对象

public class Str {public static void main(String[] args) {String str1="aaa";String str2="aaa";System.out.println(str1==str2);   }
}// 运行结果:
// true

采用字面值的方式创建一个字符串时,JVM 首先会去字符串池中查找是否存在 "aaa" 这个对象,如果不存在,则在字符串池中创建 "aaa" 这个对象,然后将池中 "aaa" 这个对象的引用地址返回给字符串常量 str,这样 str 会指向池中"aaa"这个字符串对象;如果存在,则不创建任何对象,直接将池中 "aaa" 这个对象的地址返回,赋给字符串常量
对于上述的例子:这是因为,创建字符串对象 str2 时,字符串池中已经存在 “aaa” 这个对象,直接把对象 “aaa” 的引用地址返回给 str2,这样 str2 指向了池中 “aaa” 这个对象,也就是说 str1 和 str2 指向了同一个对象,因此语句 System.out.println(str1== str2) 输出:true。

2)采用 new 关键字新建一个字符串对象

public class Str {public static void main(String[] args) {String str1=new String("aaa");String str2=new String("aaa");System.out.println(str1==str2);}
}// 运行结果:
// false

采用 new 关键字新建一个字符串对象时,JVM 首先在字符串常量池中查找有没有 "aaa" 这个字符串对象,如果有,则不在池中再去创建 "aaa" 这个对象了,直接在堆中创建一个 "aaa" 字符串对象,然后将堆中的这个"aaa"对象的地址返回赋给引用 str1,这样,str1 就指向了堆中创建的这个 "aaa" 字符串对象;如果没有,则首先在字符串常量池池中创建一个 "aaa" 字符串对象,然后再在堆中创建一个 "aaa" 字符串对象,然后将堆中这个 "aaa" 字符串对象的地址返回赋给 str1 引用,这样,str1 指向了堆中创建的这个 "aaa" 字符串对象
对于上述的例子:因为,采用new关键字创建对象时,每次new出来的都是一个新的对象,也即是说引用str1和str2指向的是两个不同的对象,因此语句
System.out.println(str1 == str2)输出:false

(3)字符串池的实现

由于字符串池是虚拟机层面的技术,所以在 String 的类定义中并没有类似 IntegerCache 这样的对象池,String 类中提及缓存/池的概念只有 intern() 这个方法。

/**
* 返回一个标准的字符串对象。
*
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
*
* 当 intern 方法被调用,若池中包含一个被{@link #equals(Object)}方法认定为和该
* String对象相等的String,那么返回池中的String,否则,将该String对象添加到池中
* 并返回它的引用。
*
* All literal strings and string-valued constant expressions are
* interned.
*/ 
public native String intern(); 

intern() 是一个native 的方法,那么说明它本身并不是由 Java 语言实现的,而是通过 jni (Java Native Interface)调用了其他语言(如C/C++)实现的一些外部方法。
大体实现:Java 调用 c++ 实现的 StringTable 的 intern() 方法。StringTable 的 intern() 方法跟 Java 中的 HashMap 的实现是差不多的,只是不能自动扩容,默认大小是1009。
字符串池(String pool)实际上是一个 HashTable。Java 中 HashMap 和 HashTable 的原理大同小异,将字符串池看作哈希表更便于我们套用学习数据结构时的一些知识。比如解决数据冲突时,HashMap 和 HashTable 使用的是开散列(或者说拉链法)。

(5)字符串池的优缺点

字符串池的优点就是避免了相同内容的字符串的创建,节省了内存,省去了创建相同字符串的时间,同时提升了性能;另一方面,字符串池的缺点就是牺牲了JVM在常量池中遍历对象所需要的时间,不过其时间成本相比而言比较低。

总结

1、全局字符串常量池在每个 VM 中只有一份,存放的是字符串常量的引用值。
2、class 常量池是在编译的时候每个 class 都有的,在编译阶段,存放的是常量的符号引用。
3、运行时常量池是在类加载完成之后,将每个 class 常量池中的符号引用值转存到运行时常量池中,也就是说,每个 class 都有一个运行时常量池,类在解析之后,将符号引用替换成直接引用,与全局常量池中的引用值保持一致。


http://chatgpt.dhexx.cn/article/ofgYoOMM.shtml

相关文章

JAVA常量池,一篇文章就足够入门了。(含图解)

前言 一直在《深入理解JVM》对常量池只有一个浅薄的了解,之前也遇到过这种题目,今天还是要挑出来进行一次全方位的了解。 常量池分类 常量池大体可以分为:静态常量池,运行时常量池。 静态常量池 存在于class文件中&#xff0c…

基于Elman神经网络的刀具剩余使用寿命预测(初学者+matlab代码实现)

1.Elman介绍 Elman神经网络是 J. L. Elman于1990年首先针对语音处理问题而提出来的,是一种典型的局部回归网络( global feed forward local recurrent)。Elman网络可以看作是一个具有局部记忆单元和局部反馈连接的递归神经网络 它的主要结构是前馈连接, 包括输入层、…

通过模拟退火改进的Elman神经网络(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 神经网络是一个庞大的体系和概念,根据处理信息的不同方式来区分不同的network。比如根据处理信息结果的传递方向&am…

基于遗传算法优化的Elman神经网络数据预测-附代码

基于遗传算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于遗传算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于遗传优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要:针…

【预测模型-ELAMN预测】基于海鸥算法优化ELMAN神经网络实现数据回归预测

1 简介 风能,作为一种重要,有潜力,无污染,可再生、可持续的能源,已经成为全球发电最为迅速的能源之一,越来越受到世界各国的青睐。近年来,为缓解能源短缺问题,改善环境,实现经济乃至人类的可持续发展,世界各国纷纷大力发展风能资源。然而,在实际操作中,风能固有的波动性和间歇…

MATLAB神经网络应用之Elman神经网络

Elman神经网络通常由输入层、隐含层和输出层构成,它存在从隐含层的输出到隐含层输入的反馈。这种反馈连接的结构使得被训练后不仅能识别和产生空域模式,还能够识别和产生时域模式,在此只介绍创建Elman网络的newelm函数,该函数用于…

基于粒子群算法优化的Elman神经网络数据预测-附代码

基于粒子群算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于粒子群算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于粒子群优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&#x…

elman神经网络的实现

在看文章时,一篇文章提到了使用elman神经网络来对癫痫病人的脑电信号与正常人的脑电信号进行区分,并且取得了较好的分类结果。于是就想自己写一个elman神经网络demo看看效果。 elman神经网络和感知机的差别通过下面的图片可以很明显的看出哪里不一样&am…

【预测模型-ELAMN预测】基于遗传算法优化ELMAN神经网络实现数据回归预测matlab代码

1 简介 风能,作为一种重要,有潜力,无污染,可再生、可持续的能源,已经成为全球发电最为迅速的能源之一,越来越受到世界各国的青睐。近年来,为缓解能源短缺问题,改善环境,实现经济乃至人类的可持续发展,世界各国纷纷大力发展风能资源。然而,在实际操作中,风能固有的波动性和间歇…

【预测模型】基于Elman神经网络预测电力负荷matlab代码

​1 简介 为提高甘肃电网负荷预测精度,提出了一种基于神经网络的负荷预测方法.针对甘肃电力系统负荷数据的非线性和动态特性,在多层前向BP网络中引入特殊关联层,形成有"记忆"能力的Elman神经网络,从而可以映射系统的非线性和动态特性.在网络训练算法中,采用自适应学…

粒子群算法优化BP和Elman神经网络-matlab源码

粒子群优化算法是一种智能优化算法,又称微粒群算法,它通过模拟自然界鸟群捕食和鱼群捕食的过程。通过群体中的协作寻找到问题的全局最优解。 收敛性的数学证明帮助了PSO的发展和应用,但此内分析具有很大的局限性。为PSO加入正交学习后&#…

基于鲸鱼算法优化的Elman神经网络数据预测-附代码

基于鲸鱼算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于鲸鱼算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于鲸鱼优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要:针…

基于小波Elman神经网络的短期风电功率预测

风力发电在全球范围内快速发展,装机容量逐年增加,截止2013 年底,中国风电新增装机容量约 16.1GW,较 2012 年的 12.96GW 大幅提高了 24%,中国风电累计装机已超过 90GW。 风力发电并网运行是实现大规模风能发利用的有效途径。但是与常规能源不…

基于灰狼算法优化的Elman神经网络数据预测

基于灰狼算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于灰狼算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于灰狼优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要:针…

Elman神经网络

newelm()函数: clear ; close all; clc %原始数据 data[0.4413,0.4707,0.6953,0.8133;...0.4379,0.4677,0.6981,0.8002;...0.4517,0.4725,0.7006,0.8201;...0.4557,0.4790,0.7019,0.8211;...0.4601,0.4811,0.7101,0.8298;...0.4612,0.4845,0.7188,0.8312;...0.4615,…

Elman神经网络与自适应共振网络(ART)

这几天在回过头看一些比较基础的东西,发现了两个早期研究的神经网络,Elman与ART网络,类似于上世纪80年代的hopfield神经网络,BM/RBM/DBN,RBF,SOM,以及同时期的SVM算法等等,虽然那个时…

Elman神经网络原理

Elman神经网络 近期开题,阅读到了一篇文章关于故障诊断的,其中用到了Elman神经网络,具体是结合EMD、PCA-SOM的Elman的性能评估/预测故障诊断,对Elman神经网络有点陌生,网上资源也讲的特别杂,来做个汇总Int…

【神经网络第一期】Elman神经网络基本原理

1. Elman神经网络概述 根据神经网络运行过程中的信息流向,可将神经网络可分为前馈式和反馈式两种基本类型。前馈式网络通过引人隐藏层以及非线性转移函数可以实现复杂的非线性映射功能。但前馈式网络的输出仅由当前输入和权矩阵决定,而与网络先前的输出…

回归预测 基于ELMAN递归神经网络预测及其matlab代码实现

文章目录 1. ELMAN神经网络的简介和算法描述1.1 Elman网络介绍1.2 Elman结构组成 1.3 ELMAN训练界面的参数解读2. 建立ELMAN神经网络的步骤3. 编写MATLAB代码4. ELMAN程序运行结果4.1 各层的神经元个数的确定过程4.2 预测值和真实值的误差计算(SSE、MAE、MSE、RMSE、…

Elman神经网络介绍以及Matlab实现

Elman神经网络介绍 1.特点 Elman神经网络是一种典型的动态递归神经网络,它是在BP网络基本结构的基础上,在隐含层增加一个承接层,作为一步延时算子,达到记忆的目的,从而使系统具有适应时变特性的能力,增强了…