Java 中的常量池

Java 中的常量池(Constant Pool)是用于存放程序中常量(如字符串、数字、类、方法等)的内存区域。常量池的主要作用是提高内存的使用效率和性能,避免重复创建相同的常量实例。

常量池主要分为两种类型:

1. 字符串常量池(String Constant Pool)

  • 定义:字符串常量池是 JVM 在运行时维护的一个特殊的常量池,它用于存储字符串字面量(literal)和字符串常量。

  • 特性

    • 字符串字面量会被自动添加到字符串常量池中,例如:String str = "Hello";
    • 对于相同的字符串字面量,JVM 会返回常量池中已存在的对象,而不是重新创建新的字符串对象,这样可以节省内存。
    • 字符串常量池是一个堆外的存储区域。
  • 使用示例

  String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // 输出 true,因为它们指向同一个字符串对象

2. 类和方法常量池(Class and Method Constant Pool)

  • 定义:每个类或接口在编译后都会有一个类常量池,它用于存储类、方法、字段的符号引用。
  • 特性
    • 包含类名、字段名、方法名等符号引用,在类加载时,JVM 会将这些符号引用解析为直接引用。
    • 类常量池在 .class 文件中,由编译器生成,包含所有类相关的信息,如方法的描述符、常量值等。

3. 常量池的工作原理

  • 编译时常量:如 final 修饰的常量值,会在编译时存储到常量池中。
  • 运行时常量:字符串字面量、常量表达式(如 1 + 2)等在运行时被添加到常量池。

4. 常量池与内存

  • 堆外内存:字符串常量池是 JVM 堆外的内存区域,而类和方法的常量池是包含在每个类的 .class 文件中的。

5. 常量池的优点

  • 节省内存:通过共享常量池,避免重复创建相同的常量实例,提高内存使用效率。
  • 提高性能:常量池中的常量在整个 JVM 运行期间可以共享,提高了代码的执行效率。
  • 减少内存碎片:通过复用常量,减少了频繁的内存分配和垃圾回收的开销。

错误信息

  • 常量池溢出:由于字符串常量池是有限制的,如果常量池中存储了过多字符串字面量,可能会遇到内存溢出。此时会抛出 OutOfMemoryError,错误信息如下:

    java.lang.OutOfMemoryError: PermGen space

总结

  • 字符串常量池:存储所有字符串字面量,避免重复创建相同的字符串对象。
  • 类和方法常量池:包含类、方法、字段的符号引用,在类加载时进行解析。
  • 内存管理:常量池在堆外存储,通过共享常量对象节省内存并提高性能。
  • 优点:减少内存占用、提高性能和内存回收效率。

    常量池是 JVM 中的一项优化机制,广泛应用于字符串、常量和类的符号引用管理。

什么是 Java 中的常量池?的更多相关文章

  1. 【Java_基础】java中的常量池

    1.java常量池的介绍 java中的常量池,通常指的是运行时常量池,它是方法区的一部分,一个jvm实例只有一个运行常量池,各线程间共享该运行常量池. java常量池简介:java常量池中保存了一份在 ...

  2. Java中的常量池

    JVM中有: Class文件常量池.运行时常量池.全局字符串常量池.基本类型包装类对象 常量池 Class文件常量池: class文件是一组以字节为单位的二进制数据流,在java代码的编译期间,编写的 ...

  3. java中Integer常量池

    我们先看一个关于Integer的例子 public static void main(String[] args) { // TeODO Auto-generated method stu Integ ...

  4. Java中的常量池(字符串常量池、class常量池和运行时常量池)

    转载. https://blog.csdn.net/zm13007310400/article/details/77534349 简介: 这几天在看Java虚拟机方面的知识时,看到了有几种不同常量池的 ...

  5. 19、java内存分配 常量池详解

    在class文件中,“常量池”是最复杂也最值得关注的内容. Java是一种动态连接的语言,常量池的作用非常重要,常量池中除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如Stri ...

  6. 【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

    碎碎念 关于JDK源码相关的文章这已经是第四篇了,原创不易,粉丝从几十人到昨天的666人,真的很感谢之前帮我转发文章的一些朋友们. 从16年开始写技术文章,到现在博客园已经发表了222篇文章,大多数都 ...

  7. Java字面常量与常量池

    Java中的字面常量(区别于final创建的有名常量)通常会保存在常量池中,常量池可以理解为像堆一样的内存区域.但是常量池有一个特性就是,如果常量池中已存在该常量将不会再次为该常量开辟内存 还是看个程 ...

  8. jdk1.7中的常量池

    在探究jdk1.7中的常量池,我们可以先看看以下的这段代码 public static void main(String[] args) throws Throwable { List<Stri ...

  9. 第46节:Java当中的常量池

    Java当中的常量池 在Java虚拟机jvm中,内存分布为:虚拟机堆,程序计数器,本地方法栈,虚拟机栈,方法区. 程序计数器是jvm执行程序的流水线,是用来存放一些指令的,本地方法栈是jvm操作系统方 ...

  10. 关于jvm中的常量池和String.intern()理解

    1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ne ...

随机推荐

  1. SQL Server统计信息更新会被阻塞或引起会话阻塞吗?

    在SQL Server数据库中,统计信息更新(UPDATE STATISTICS)会被其它会话阻塞吗?统计信息更新(UPDATE STATISTICS)会引起其它会话阻塞吗?在回答这两个问题前,我们必 ...

  2. jenkins+svn+tomcat

    1.安装插件即可在源码管理中看见svn的选项subversion2.源码管理中配置svn的工程地址 3.点击Credentials的[添加]配置svn的用户名密码,完成后选取即可 4.配置构建触发器, ...

  3. CentOS7安装RabbitMQ (安装包安装)

    环境: CentOS7 需要安装:erlang 22.2  rabbitmq 3.8.3 参考: rabbit官网地址:http://www.rabbitmq.com/which-erlang.htm ...

  4. 傻妞教程——如何获取天行数据服务的Key

    在傻妞插件列表中,比如油价查询.舔狗语录等需要申请天行KEY,才能使用 1.打开 天行数据官网注册登录 2.在控制台首页完成实名认证 3.在左侧数据管理里面获取你的秘钥Key 4.回到傻妞已安装的插件 ...

  5. flutter - [02] 基本语法

    题记部分 一.注释 ///这是一个注释 //这也是个注释 /* 这还是个注释 */ void main(List<String> args) { print ('你好 dart'); } ...

  6. 开源一款数据转换扩展板-FreakStudio多米诺系列

    原文链接: FreakStudio的博客 摘要 数据转换板通过I2C接口进行信号采集和输出,支持最多16通道输入和2通道输出.具备860Hz采样率和50KHz输出频率,采用16位ADC和12位DAC芯 ...

  7. Scala高阶函数 1

    package com.wyh.day01 /** * * 高阶函数 */ object ScalaFun3 { def main(args: Array[String]): Unit = { //定 ...

  8. 2024NOIP邮寄

    渺渺兮身外无物,无喜无悲无怖,不过是大梦一场,各自沉浮. 前言 原计划这篇游记兼总结是在考完后一天之内写出来(12.1 前),但是一方面是因为家里的笔记本插上 U 盘写不了东西,一方面是这次 NOIP ...

  9. 基于Microsoft.Extensions.AI核心库实现RAG应用

    大家好,我是Edison. 之前我们了解 Microsoft.Extensions.AI 和 Microsoft.Extensions.VectorData 两个重要的AI应用核心库.基于对他们的了解 ...

  10. CCRC软件开发评审-材料应该怎么准备

    1. 什么是CCRC软件开发评审 软件安全开发资质认证是对软件开发方的基本资格.管理能力.技术能力和软件安全过程能力等方面进行评价全软件开发服务资质级别是衡量服务提供方的软件安全开发服务资格和能力的尺 ...