JVM中的运行时常量池详解

        运行时常量池(Runtime Constant Pool)是每一个类或接口的常量池(Constant_Pool)的运行时表示形式,它包括了若干种不同的常量:从编译期可知的数值字面量到必须运行期解析后才能获得的方法或字段引用。运行时常量池扮演了类似传统语言中符号表(Symbol Table)的角色,不过它存储数据范围比通常意义上的符号表要更为广泛。

        每一个运行时常量池都分配在Java虚拟机的方法区之中,在类和接口被加载到虚拟机后,对应的运行时常量池就被创建出来。

         在创建类和接口的运行时常量池时,可能会发生如下异常情况:

 当创建类或接口的时候,如果构造运行时常量池所需要的内存空间超过了方法区所能提供的最 大值,那Java虚拟机将会抛出一个OutOfMemoryError异常。

        上面的表述实在有些晦涩,不易初学者理解,所以下面我通过一个详细的例子,用通俗的语言一步步带你理解“运行时常量池”是怎么工作的。


假设我们写了一段简单的 Java 代码:

public class Example {public static void main(String[] args) {int number = 42;String message = "Hello, World!";System.out.println(message);}
}

第一步:代码编译成 .class 文件

        当你用 javac Example.java 编译这段代码时,Java 编译器会生成一个 Example.class 文件。这个文件里有一个“常量池”(Constant Pool),它就像一个清单列表,把代码里用到的“固定信息”列出来。这些信息在编译时就已经确定了,但它们只是“符号”或者“名字”,还没有变成程序运行时能直接用的东西。

在这个例子中,常量池里可能会记录这些内容:

  1. 数字 42(一个整数字面量)。
  2. 字符串 "Hello, World!"(一个字符串字面量)。
  3. 方法引用 System.out.println(表示我们要调用的那个打印方法)。
  4. 一些类名和字段名,比如 java/lang/System 和 out

这些信息被存成一种特殊的格式,比如:

  • #1 = Integer 42(表示数字 42)。
  • #2 = String "Hello, World!"(表示字符串)。
  • #3 = Methodref java/lang/System.out.println(表示打印方法)。

        这些只是符号,不是最终的内存地址或实际数据。常量池就像一个“备忘录”,记录了代码里用到的所有关键东西。

第二步:JVM 加载并创建运行时常量池

        当你运行 java Example 时,JVM 会加载 Example.class 文件。它会把文件里的常量池拿出来,变成一个“活的”东西——这就是“运行时常量池”(Runtime Constant Pool)。这个运行时常量池存在于 JVM 的内存中(具体在方法区里),它的任务是把刚才那些符号“翻译”成程序能用的实际内容。

比如:

  • 数字 42:在运行时常量池里,它还是 42,但会被关联到程序的计算中,直接用在 int number = 42 赋值。
  • 字符串 "Hello, World!":JVM 会检查字符串池(String Pool,专门用来存字符串),如果池子里已经有 "Hello, World!",就直接用那个;如果没有,就创建一个新的字符串对象,然后把它的引用存到运行时常量池里。
  • 方法 System.out.println:运行时常量池会去查找 System 类的具体位置,找到 out 这个字段(它是一个 PrintStream 对象),再找到 println 方法的实际内存地址。这样,程序就知道去哪里执行打印操作。

第三步:程序运行时的翻译过程

现在程序开始执行 main 方法:

  1. int number = 42;

    • JVM 直接从运行时常量池拿到 42,把它赋值给变量 number。这里没什么复杂的,因为 42 是个简单的数字。
  2. String message = "Hello, World!";

    • JVM 从运行时常量池里找到 "Hello, World!" 的引用。因为它是字符串字面量,JVM 会确保它在字符串池里只存在一份,然后让 message 指向这个字符串。
  3. System.out.println(message);

    • JVM 去运行时常量池查找 System.out.println 的符号引用。
    • 它先找到 System 类(可能在内存地址比如 0x1234),然后找到 out 字段(一个 PrintStream 对象,比如在 0x5678),再找到 println 方法的具体地址(比如 0x9abc)。
    • 最后,JVM 调用这个方法,把 message 的内容 "Hello, World!" 打印出来。

比喻解释:运行时常量池像一个“翻译官”

想象你去一个陌生的国家旅游,带了一本旅游手册,里面写着:

  • “酒店” 在第 1 页。
  • “问候语:你好” 在第 2 页。
  • “找餐厅的方法” 在第 3 页。

        这本手册就像编译时的“常量池”,它只是记录了信息,但你还不知道具体怎么用。到了当地,你请了个导游(运行时常量池),他拿着手册帮你翻译:

  • “酒店” → 带你去具体的酒店地址。
  • “你好” → 教你怎么发音跟当地人打招呼。
  • “找餐厅的方法” → 告诉你具体的路线。

        运行时常量池就干这个活儿:把代码里的符号(手册上的词)翻译成实际能用的东西(地址、数据),让程序顺利跑起来。

总结

通过这个例子,可知运行时常量池的核心作用是:

  • 保存编译时确定的常量(数字、字符串、方法引用等)。
  • 在程序运行时,把这些符号解析成实际的内存地址或数据。
  • 确保代码里的每一部分都能找到它需要的东西,正确执行。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# MethodBase 类使用详解

总目录 前言 在C#编程中,反射(Reflection)是一种强大的机制,允许我们在运行时检查和操作类型的成员。MethodBase 类是.NET框架中 System.Reflection 命名空间下的一个抽象类,它是所有方法( MethodInfo 和 Constructor…

【css酷炫效果】纯CSS实现3D翻转卡片动画

【css酷炫效果】纯CSS实现3D翻转卡片动画 缘创作背景html结构css样式完整代码效果图 想直接拿走的老板,链接放在这里:https://download.csdn.net/download/u011561335/90490472 缘 创作随缘,不定时更新。 创作背景 刚看到csdn出活动了&am…

Flask多参数模版使用

需要建立目录templates; 把建好的html文件放到templates目录里面; 约定好参数名字,单个名字可以直接使用;多参数使用字典传递; 样例: from flask import render_template # 模板 (Templates) #Flask 使用…

SVN简明教程——下载安装使用

SVN教程目录 一、开发中的实际问题二、简介2.1 版本控制2.2 Subversion2.3 Subversion的优良特性2.4 工作原理2.5 SVN基本操作 三、Subversion的安装与配置1. 服务器端程序版本2. 下载源码包3. 下载二进制安装包4. 安装5. 配置版本库① 为什么要配置版本库?② 创建目…

OpenCV图像拼接(1)概述

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 此图说明了在Stitcher类中实现的拼接模块流程。使用该类,可以配置/移除某些步骤,即根据特定需求调整拼接流程。流程中的所…

Ubuntu20.04安装Nvidia显卡驱动

Ubuntu20.04安装Nvidia显卡驱动 安装环境为Dell R540服务器 官网下载Nvidia显卡驱动 https://www.nvidia.cn/geforce/drivers/ 安装显卡驱动 chmod x NVIDIA-Linux-x86_64-470.63.01.run sudo ./NVIDIA-Linux-x86_64-470.63.01.run 遇到nouveau报错 lsmod查看nouveau驱动…

互联网it常用抓包工具说明

一、引言 在互联网 IT 领域,无论是网络故障排查、安全检测,还是开发调试,抓包工具都发挥着举足轻重的作用。 当网络出现故障,比如网页加载缓慢、应用无法连接服务器时,抓包工具可以帮助我们捕获网络数据包&#xff0…

Linux 音频驱动 WM8960 音频 DAC IC 音乐播放与录音

这些先引出一个内容,是 Linux 内核的音频系统,ALSA,提供了对声卡的低级访问,支持 PCM,播放/录音、混音、MIDI 处理等功能。它取代了旧的 OSS,并提供更强大的功能和更好的硬件支持。 ALSA 主要特点&#xf…

k8s中的组件

1.namespace Namespace 用于将集群资源划分为不同的逻辑组&#xff0c;方便管理和隔离 kubectl get namespace 查看所有逻辑组 kubectl describe namespace <namespace-name> 查看某个逻辑组信息详情 kubectl create namespace ... 创建逻辑组 kubectl delete names…

OpenHarmony 开源鸿蒙北向开发——3.配置SDK

安装、配置完成之后我们就要配置SDK。 我们创建工程后&#xff0c;点击右上角设置 进入设置 进入OpenHarmony SDK&#xff0c;选择编辑 这里配置一下SDK安装位置 点击完成 这里我们API版本勾选第一个即可 确认安装 勾选接受 这里要等一会 安装完成后&#xff0c;点击完成

5.2《生活中的透镜》——5.3《凸透镜成像规律》讲后再上

教会什么:照相机、投影仪、放大镜的原理 培养什么:(再说) 课标: (二)运动和相互作用 2.3 声和光 2.3.5了解凸透镜成像规律的应用。 例7 了解凸透镜成像规律在放大镜、照相机中的应用。 一、导入 提问:生活中有哪些透镜?(放大镜、照相机、投影仪/幻灯机) ——直接提出…

怎么用LoRA的低秩结构近似Fisher矩阵

怎么用LoRA的低秩结构近似Fisher矩阵 目录 怎么用LoRA的低秩结构近似Fisher矩阵**1. Fisher矩阵的内存挑战****2. LoRA的低秩结构与Fisher近似****3. 具体实现步骤****4. 示例说明****5. 有效性分析****6. 扩展与优化****总结**在LoRA(低秩适应)中,通过低秩结构近似Fisher矩…

C#通过API接口返回流式响应内容---SignalR方式

1、背景 在上两篇《C#通过API接口返回流式响应内容—分块编码方式》和《C#通过API接口返回流式响应内容—SSE方式》实现了流式响应的内容。 上面的这两个主要是通过HTTP的一些功能&#xff0c;除了这些之外&#xff0c;还有WebSocket的方式。C#中的WebSocket的有比较多的方案&…

Redis 跳表原理详解

一、引言 在 Redis 中&#xff0c;有序集合&#xff08;Sorted Set&#xff09;是一种非常重要的数据结构&#xff0c;它可以实现元素的有序存储和高效查找。而实现有序集合的底层数据结构之一就是跳表&#xff08;Skip List&#xff09;。跳表是一种随机化的数据结构&#xff…

识别并脱敏上传到deepseek/chatgpt的文本文件中的身份证/手机号

本文将介绍一种简单高效的方法解决用户在上传文件到DeepSeek、ChatGPT,文心一言,AI等大语言模型平台过程中的身份证号以及手机号等敏感数据识别和脱敏问题。 DeepSeek、ChatGPT,Qwen,Claude等AI平台工具快速的被接受和使用,用户每天上传的文本数据中潜藏着大量敏感信息,…

Spring 如何创建 Bean 实例的?

Spring 创建 Bean 实例的过程主要由 BeanFactory 接口及其实现类&#xff08;通常是 AbstractBeanFactory 的 doGetBean 方法和 DefaultListableBeanFactory 的 preInstantiateSingletons 方法&#xff09;负责。这个过程涉及多个步骤&#xff0c;包括 Bean 定义的解析、依赖的…

第六:go 操作 redis-go

Redis 在项目开发中redis的使用也比较频繁&#xff0c;本文介绍了Go语言中go-redis库的基本使用。 Redis介绍 Redis是一个开源的内存数据库&#xff0c;Redis提供了多种不同类型的数据结构&#xff0c;很多业务场景下的问题都可以很自然地映射到这些数据结构上。除此之外&am…

【RabbitMQ】RabbitMQ如何保证消息不丢失?

为了保证消息不丢失&#xff0c;需要在生产者、RabbitMQ本身和消费者三个环节采取相应措施。 1.生产者端&#xff1a;确保消息发送成功 1.1开启消息确认机制(Publisher Confirms) 原理&#xff1a; 生产者发送消息后&#xff0c;RabbitMQ会返回一个确认(ACK),表示消息已成功…

fastapi+angular外卖系统

说明&#xff1a; fastapiangular外卖系统 1.美食分类&#xff08;粥&#xff0c;粉&#xff0c;面&#xff0c;炸鸡&#xff0c;炒菜&#xff0c;西餐&#xff0c;奶茶等等&#xff09; 2.商家列表 &#xff08;kfc&#xff0c;兰州拉面&#xff0c;湘菜馆&#xff0c;早餐店…

Kafka-Exporter 9308端口启用TLS认证的完整指南

#作者&#xff1a;张桐瑞 文章目录 1 方案描述2 涉及版本3 使用CA自签证书3.1一键生成证书脚本3.1.1证书脚本3.1.2执行结果 3.2分步自建证书过程3.2.1生成CA私钥3.2.2生成CA自签名证书3.2.3生成服务器私钥和证书申请文件CRS 3.3最终的文件列表 4 Exporter启动命令4.1参数说明 …