class常量池、运行时常量池和字符串常量池的关系

类常量池、运行时常量池和字符串常量池这三种常量池,在Java中扮演着不同但又相互关联的角色。理解它们之间的关系,有助于深入理解Java虚拟机(JVM)的内部工作机制,尤其是在类加载、内存分配和字符串处理方面。

类常量池(Class Constant Pool)

每个Java类文件(.class文件)都具有自己的类常量池,它用于存储编译期生成的常量,包括各种字面量(字面量就是指由字母、数字等构成的字符串或者数值)和符号引用(比如类和接口的全名、字段的名称和描述符、方法的名称和描述符)。类常量池在编译期间就已经被确定,并被保存在.class文件中。

Class常量池是用来保存常量的一个中间场所。在JVM真的运行时,需要把类常量池中的常量加载到内存中的运行时常量池中。

运行时常量池(Runtime Constant Pool)

运行时常量池是类被加载到JVM时类常量池的内存版本:当Java类被加载到JVM时,各个类文件中的类常量池内容被读取并存入到运行时常量池中,其中字符串的部分直接进到字符串池,其他常量进入到运行时常量池。

根据Java虚拟机规范约定:每一个运行时常量池都在Java虚拟机的方法区中分配,在加载类和接口到虚拟机后,就创建对应的运行时常量池。

规范中规定了运行时常量池属于方法区,但是没规定方法区属于哪。于是虚拟机在各自实现的时候就各显神通了。在不同版本的JDK中,运行时常量池所处的位置也不一样。以HotSpot虚拟机为例:

在JDK 1.7之前,方法区位于永久代,运行时常量池作为方法区的一部分,处于永久代中,字符串常量池位于运行时常量池的一部分也处于永久代中。

jdk1.7之间jvm内存结构
因为使用永久代实现方法区可能导致内存泄露问题,所以,从JDK1.7开始,JVM尝试解决这一问题。

在JDK 1.7中,静态变量和运行时常量池中的字符串常量池转移到了堆内存中,其他类型的常量还保留在方法区中。
在这里插入图片描述
在JDK 1.8中,彻底移除了永久代,方法区通过元空间的方式实现,元空间是使用本地内存(Native Memory)来存储类的元数据信息的。随之,运行时常量池也在元空间中实现。
在这里插入图片描述

运行时常量池中包含了若干种不同的常量,他的来源主要有两种:

  • 编译期可知的字面量和符号引用(来自Class常量池)

  • 运行期解析后可获得的常量(如String的intern方法)

字符串常量池(String Constant Pool)

字符串常量池专门用于存储字符串常量。对于 Hotspot 虚拟机来说,类加载时,字符串字面量作为类常量池的一部分信息被载入运行时常量池中,它们以特殊的形式存储在运行时常量池中,此时它们并未被实例化为Java堆中的String对象。只有当这个字符串字面量被调用时,才会对其进行解析,即检查字符串常量池中是否已经存在相同内容的字符串对象。如果存在,就直接返回指向该对象的引用,如果不存在,虚拟机会在字符串常量池中创建一个对应的String实例,并返回这个新实例的引用。

这种处理方式的优势在于,可以减少在类加载阶段对内存的需求和降低开销,因为不是所有的字符串字面量在类的使用周期内都会被用到。同时,此方法延迟了String对象的实例化,直到它们真正被需要,这有助于提高性能并减少内存的无谓占用。

为什么从JDK 1.7开始,字符串常量池从永久代中挪到堆(Heap)中?

主要原因是因为永久代的 GC 回收效率太低,只有在FulIGC的时候才会被执行回收。但是Java中往往会有很多字符串的生命周期都很短暂,将字符串常量池放到堆中,能够更高效及时地回收字符串内存。

字符串常量池中的常量有以下几个来源:
1、字面量常量。
在代码中直接使用双引号括起来的字符串字面值(如 strings="hello”)会被认为是常量,并且会在编译后进入class文件的常量池,并且在运行阶段,进入字符串常量池。这是最常见的字符串常量来源。
2、intern()方法
String类提供了一个intern方法,用于将字符串对象手动添加到字符串常量池中。调用intern()方法时,如果字符串常量池中已经存在相同内容的字符串,将会返回常量池中的引用;如果不存在,则会在常量池中添加该字符串在堆中的引用。

要注意的是,字符串常量池是一个固定大小的Hashtable,默认值大小长度是1009,如果放进字符串常量池的String非常多,就会造成Hash冲突严重,从而导致链表会很长,而链表长了后直接会造成的影响就是当调用String.intern时性能会大幅下降(因为要一个一个找,以此判断字符串常量在不在字符串常量池中)。在jdk6中StringTable是固定的,就是1009的长度,所以如果常量池中的字符串过多就会导致效率下降很快。在jdk7中,StringTable的长度可以通过一个参数指定:

-XX:StringTableSize=99991

还有一个值得注意的点:
对于字符串的拼接,纯字面量和字面量的拼接,会把拼接结果作为常量保存到字符串池。如果在字符串拼接中,有一个参数是非字面量,而是一个变量的话,整个拼接操作会被编译成StringBuilder.append,这种情况编译器是无法知道其确定值的。只有在运行期才能确定。
比如这段代码:

string s1 = "Hollis";
string s2 = "Chuang";
string s3 = s1 + s2;
string s4 = "Hollis" + "Chuang";

在经过反编译后得到代码如下:

String s1 = "Hollis";
string s2 = "chuang" ;
string s3 = (new stringBuilder() ).append(s1).append(s2).toString( );
String s4 = "Hollischuang";

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/621348.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【java9】java9新特性概述

经过4次的跳票,历经曲折的Java9最终在2017年9月21日发布。因为里面加入的模块化系统,在最初设想的时候并没有想过那么复杂,花费的时间超出预估时间。距离java8大约三年时间。 Java9提供了超过150项新功能特性,包括备受期待的模块…

sql注入---sqli靶场

1.什么是SQL注入 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库 2.sql注入原理 攻击者注入一段包含注释符的SQL语…

软件2班20240513

第三次作业 package com.yanyu;import java.sql.*; import java.util.ResourceBundle;public class JDBCTest01 {public static void main(String[] args) {ResourceBundle bundle ResourceBundle.getBundle("com/resources/db");// ctrl alt vString driver …

WebSocket建立网络连接——小案例

WebSocket是一种实现全双工通信的网络技术标准,它允许在用户的浏览器和服务器之间进行持久的、双向的通信。以下是对WebSocket的具体介绍: 实时性:与传统HTTP请求相比,WebSocket提供了更高效的实时数据交换方式。一旦建立连接&am…

极限基本思想

极限基本思想 在高等数学中极限是微积分的前置思想,没有极限的概念,那么微积分的理论将不复存在。极限也用于分析一个函数的连续性,可以说理解极限后理解函数的连续问题是轻而易举的事情。对于函数的连续性,不是什么高深的词汇就…

点云分割论文阅读01--FusionVision

FusionVision: A Comprehensive Approach of 3D Object Reconstruction and Segmentation from RGB-D Cameras Using YOLO and Fast Segment Anything FusionVision:使用 YOLO 和 Fast Segment Anything 从 RGB-D 相机重建和分割 3D 对象的综合方法 toread&#x…

linux笔记5--shell命令2

文章目录 一. linux中的任务管理1. 图形界面2. 命令① top命令② grep命令③ ps命令补充: ④ kill命令图形界面杀死进程 二. 挂载(硬盘方面最重要的一个知识点)1. 什么是挂载2. 关于挂载目录① Windows② linux查看硬件分区情况(/dev下):更改挂载目录结束…

MySQL—子查询

目录 ▐ 子查询概述 ▐ 准备工作 ▐ 标量子查询 ▐ 列子查询 ▐ 表子查询 ▐ 多信息嵌套 ▐ 子查询概述 • 子查询也称嵌套查询,即在一个查询语句中又出现了查询语句 • 子查询可以出现在from 后面 或where后面 • 出现在 from 后称表子查询,结…

【线程创建】——三种方式➕多线程案例练习

02 线程创建 Thread , Runnable , Callable 三种创建方式 Thread class - 继承Thread类 (重点) Runnable接口 - 实现Runnable接口 (重点) Callable接口 - 实现Callable接口 (了解) Thread 类实现 它继承了老祖宗 Object java.lang.Object java.lang.Thread 它实现了 Runnab…

DEV--C++小游戏(吃星星(0.5))

目录 吃星星(0.5) 该版本简介 DEV--C小游戏(吃星星(0.1)) DEV--C小游戏(吃星星(0.2)) 分部代码 头文件 命名空间变量(增) 副函数(新,增) 清屏函数 打印地图函数(增&…

小红薯视频作品一键克隆,解放双手自动搬运【永久脚本+使用教程】

软件介绍: 小红薯作品搬运神器,软件只需要复制对方的作品链接即可一键克隆搬运到自己的小红书上,再也不用手动去复制粘贴了,批量起号搬运必备神器 设备需求: 电脑 链接:https://pan.baidu.com/s/11MzBqER…

15集合的应用

集合的概念 集合是一个容器,可以容纳其他类型的数据,前面所讲的数组就是一个集合。 所有的集合相关的类和接口都在java.util包下 特点 集合不能直接存储基本数据类型(但是代码上不需要体现,因为Java中有自动装箱)另外集合不能直接存储Java…

数据结构-栈的讲解

栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底(因为先进后出)。栈中的数据元素遵守后进先出LIFO(Last In Firs…

Python GraphQL服务器实现库之tartiflette使用详解

概要 Tartiflette是一个为Python编写的GraphQL服务器实现,它建立在现代异步编程库如asyncio之上,提供了高性能的GraphQL执行环境。Tartiflette专注于提供最佳的开发者体验,支持最新的GraphQL特性。 安装 安装Tartiflette相对简单,但需要依赖于一些系统级的库。 首先,需…

【话题】软件开发的航海图:程序员的实用神器探秘

大家好,我是全栈小5,欢迎阅读小5的系列文章,这是《话题》系列文章 目录 背景一、代码编写二、版本控制三、测试与调试四、部署与运维五、总结文章推荐 背景 在软件开发的广阔海洋中,每一位程序员都是一位勇敢的航海家&#xff0c…

基于STM32F401RET6智能锁项目(AT24C0X存储芯片)

一、IIC基本介绍 1、IIC通信接口 • I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线 • 两根通信线:SCL(串行时钟线)、SDA(串行数据线) • 同步,半双工 • 带数据应答 •…

Java后端的接口参数两个interger 类型情况解决

get请求 &#xff0c;对应请求头 RequestParm, post请求&#xff0c; 对应请求体 &#xff0c;RequestBody 两个Integer参数情况 GetMapping("/insertStaffClass")public R<Void> insertStaffClass(RequestParam Integer staffId,RequestParam List<Integ…

C++ | Leetcode C++题解之第75题颜色分类

题目&#xff1a; 题解&#xff1a; class Solution { public:void sortColors(vector<int>& nums) {int n nums.size();int p0 0, p2 n - 1;for (int i 0; i < p2; i) {while (i < p2 && nums[i] 2) {swap(nums[i], nums[p2]);--p2;}if (nums[i…

python跟C++选哪个?

选择使用Python还是C取决于你的具体需求和项目背景。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 在通信工程行业…

centos7安装zabbix-server

zabbixan-server安装 环境安装zabbix安装zabbix配置apachezabbix-UI前端配置修改zabbix为中文语言 环境 准备&#xff1a; centos7系统、mysql数据库/MariaDB数据库 mysql数据库可参照&#xff1a;https://blog.csdn.net/weixin_61367575/article/details/138774428?spm1001.…