《深入理解 Java 虚拟机》把这个知识点讲错了?互联网全栈架构关注共 2130字,需浏览 5分钟 ·2021-12-18 20:16 △Hollis, 一个对Coding有着独特追求的人△这是Hollis的第 380 篇原创分享作者 l Hollis来源 l Hollis(ID:hollischuang)在之前的一篇文章中,介绍过Java中的Class常量池,在Java体系中,提到常量池,除了 Class常量池,还有运行时常量池和字符串常量池等概念。很多人搞不清楚他们的区别与联系,甚至还有人曾经有人对周志明老师的《深入理解 Java虚拟机》中关于这他们之间的关系的表述产生过质疑,详见后文。那么,到底什么是运行时常量池。他和字符串池之间的关系和区别又是什么呢?Java虚拟机为每一个类型都维护了一个常量池,是 Java 虚拟机中的运行时数据结构,这里面主要存放的是编译期生成的各种字面量和符号引用,这就是运行时常量池。根据Java虚拟机规范约定:每一个运行时常量池都在Java虚拟机的方法区中分配,在加载类和接口到虚拟机后,就创建对应的运行时常量池。规范中规定了运行时常量池属于方法区,但是没规定方法区属于哪。于是虚拟机在各自实现的时候就各显神通了。JDK各个版本中的实现在不同版本的JDK中,运行时常量池所处的位置也不一样。以HotSpot虚拟机为例:在JDK 1.7之前,方法区位于永久代,运行时常量池作为方法区的一部分,也处于永久代中。因为使用永久代实现方法区可能导致内存泄露问题,所以,从JDK1.7开始,JVM尝试解决这一问题。在JDK 1.7中,静态变量和运行时常量池中的字符串常量池转移到了堆内存中,其他类型的变量还保留在方法区中。在JDK 1.8中,彻底移除了永久代,方法区通过元空间的方式实现。随之,运行时常量池也在元空间中实现。池中常量的来源运行时常量池中包含了若干种不同的常量,他的来源主要有两种:编译期可知的字面量和符号引用(来自Class常量池)运行期解析后可获得的常量(如String的intern方法)三种池之间的关系虚拟机启动过程中,会将各个Class文件中的常量池载入到运行时常量池中。所以, Class常量池只是一个媒介场所。在JVM真的运行时,需要把常量池中的常量加载到内存中,进入到运行时常量池。这就是Class 常量池和运行时常量池之间的关系。那么,字符串池(string literal pool)和运行时常量池(runtime constant pool)之间的关系和区别是什么呢?关于这个问题,很多人都有疑问。很少有人能说清楚到底这两者之间有啥具体的区别和联系。之前,就有人对周志明老师的《深入理解 Java虚拟机》中关于这二者之间的关系的表述产生过质疑,于是两个人各自举证,唇枪舌战的辩论了很久(围观地址:https://github.com/fenixsoft/jvm_book/issues/112 )。其实,这个事儿说来也简单,主要是要区分「Java虚拟机规范」和「Java虚拟机实现」首先,在官方的「Java虚拟机规范」中,明确的表示过,字符串字面量以及 intern 过的字符串内容,都是要进到运行时常量池的。规范是这么说的,所以,不管咋说,字符串常量就是要存储在运行时常量池的。但是,具体的虚拟机实现的时候,可能有些自己的想法,如 HotSpot就给字符串常量池专门搞了个池用来存储字符串常量。而有人认为这两个不是一回事的主要原因,其实,"罪魁祸首"也是HotSpot。「Java虚拟机规范」规定运行时常量池要放到方法区,但是没规定方法区要具体在哪实现。如前文说过,JDK 1.8中,彻底移除了永久代,方法区通过元空间的方式实现。运行时常量池随着去到了元空间中。但是!字符串池还保留在堆内存中。这就使得很多人认为,运行时常量池和字符串常量池好像没啥关系,所在的位置都不一样。但是其实,不管 HotSpot 具体如何实现的,其实还是遵守「Java虚拟机规范」的,虽然在 JDK 1.8中,运行时常量池和字符串池不在同一个物理区域,但是这也不能说明字符串池不属于运行时常量池。或者说,字符串池就是运行时常量池的一个逻辑子区域。及字符串池是运行时常量池的分池!所以,总结一下,Class 常量池的内容,会在编译过后在运行期进入到运行时常量池,其中字符串的部分直接进到字符串池,其他常量进入到运行时常量池。至于在运行期,如果有对字符串进行过 intern 操作,那么也可能会在运行时动态向字符串池中添加新的字符串常量!PS:本文节选自我已经写完但是还未出版的新书,敬请期待。推荐阅读:跑了4个实验,实战讲解 MySQL的行锁、间隙锁...Java 进阶之字节码剖析【硬核】秒杀活动技术方案中的Redis5 分钟复现 log4J 漏洞,手把手实现为什么CTO不写代码,还这么牛逼?面试官:HashMap有几种遍历方法?推荐使用哪种?欢迎关注微信公众号:互联网全栈架构,收取更多有价值的信息。 浏览 36点赞 评论 收藏 分享 手机扫一扫分享分享 举报 评论图片表情视频评价全部评论推荐 深入理解Java虚拟机 : JV深入理解Java虚拟机 : JV0一文深入理解 Java 虚拟机IT牧场0深入理解Java虚拟机 : JV《深入理解Java虚拟机:JVM高级特性与最佳实践》内容简介:作为一位Java程序员,你是否也曾经想深入理解Java虚拟机(第2版) 深入理解Java虚拟机(第2版) 0深入理解Java虚拟机(第3版) 内容介绍 这是一部从工作原理和工程实践两个维度深入剖析JVM的著作,是计算机领域公认的经典,繁深入理解Java虚拟机(第2版) 《深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)》内容简介:第1版两年内印刷近10次,4深入理解Java虚拟机(第3版) 深入理解Java虚拟机(第3版) 0[赠书活动]深入理解Java虚拟机-HotSpotJava学习之道0送书|深入理解 Java 虚拟机 HotSpotHelloGitHub0深入理解Java虚拟机:JVM类加载机制SegmentFault0点赞 评论 收藏 分享 手机扫一扫分享分享 举报