《深入理解 Java 虚拟机》把这个知识点讲错了?
△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:本文节选自我已经写完但是还未出版的新书,敬请期待。
技术交流群
最近有很多人问,有没有读者交流群,想知道怎么加入。
最近我创建了一些群,大家可以加入。交流群都是免费的,只需要大家加入之后不要随便发广告,多多交流技术就好了。
目前创建了多个交流群,全国交流群、北上广杭深等各地区交流群、面试交流群、资源共享群等。
有兴趣入群的同学,可长按扫描下方二维码,一定要备注:全国 Or 城市 Or 面试 Or 资源,根据格式备注,可更快被通过且邀请进群。
▲长按扫描
往期推荐
突发!Log4j 爆“核弹级”漏洞,Flink、Kafka等至少十多个项目受影响
一个员工的离职成本有多恐怖!
快手裁员30%,大部分年薪超100w?工资越高越容易被裁,你慌了吗?
如果你喜欢本文,
请长按二维码,关注 Hollis.
转发至朋友圈,是对我最大的支持。
点个 在看
喜欢是一种感觉
在看是一种支持
↘↘↘
《深入理解 Java 虚拟机》把这个知识点讲错了?相关推荐
- 自己整理的一些《深入理解Java虚拟机》的知识点
寒假阅读了<深入理解Java虚拟机(第三版)>这本书,主要阅读了该书的前七章.整理了一些JVM的知识点. JVM内存分区 程序计数器:当前线程所执行的字节码的行号指示器,是程序控制流的指示 ...
- 运用《深入理解Java虚拟机》书中知识解决实际问题
前言 以前看别人博客说看完<深入理解Java虚拟机>这本书并没有让自己的编程水平提高多少,不过却大大提高了自己的装逼水平.其实,我倒不这么认为,至少在我看完一遍这本书后,有一种醍醐灌顶的感 ...
- 《深入理解Java虚拟机》第 3 版里面到底多了哪些知识点?本文竟然得到了本书作者的认可!
这是why的第 47 篇原创文章 荒腔走板 大家好,我是 why.老规矩,先是简短的荒腔走板聊聊生活. 上面的图是前几天拍的,那天晚上下班后,刚刚走进小区就看到了这一轮弯月和旁边那一颗特别特别亮的星星 ...
- 《深入理解Java虚拟机》知识点目录
深入理解Java虚拟机 第二章 Java内存区域与内存溢出异常 2.2 运行时数据区域 p42 Java内存区域划分概述 p43 程序计数器 p43 程序计数器是唯一一个不会存在OOM的内存区域 p4 ...
- 深入理解JAVA虚拟机学习笔记(一)JVM内存模型
摘要: 上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状 ...
- 深入理解java虚拟机 -- jVM高级特性与最佳实践
<深入理解 Java 虚拟机–JVM高级特性与最佳实践> 关于这本书已经断断续续的看了好几遍了,使自己对jvm有了很深的理解,但是由于长时间的不用,对很多的功能点有所遗忘,特此写下这篇随手 ...
- 《趣学编程》深入理解Java虚拟机
哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新,可以微信搜索[小奇JAVA面试]第一时间阅 ...
- JVM篇:《深入理解Java虚拟机第二版.SUN技术》——笔记
深入理解Java虚拟机第二版.SUN技术 第1章 Java体系结构介绍 1.1 Java体系结构包括四个独立但相关的技术 1.2 虚拟机 第2章 平台无关 2.1为什么要平台无关 2.2Java体系结 ...
- 【深入理解Java虚拟机】保姆级整理汇总 第一部分:走近Java (一) Java技术体系
目录 一.开篇感言 二.正文 1.Java技术体系 1.1 Java技术体系介绍 1.2 JDK和JRE范围 1.3 Java主要产品线 1.4 Java发展史 1.5 Java虚拟机家族 一.开篇感 ...
最新文章
- colorAccent,colorPrimary,colorPrimaryDark 作用的地方
- 串口基础类库(WIN32)异步通信 _COM_H 源代码
- 浙江理工大学2019年5月赛
- go 安装 mysql 链接驱动
- 使用STL去除std::vector自定义结构体重复项
- sphereface 训练出现的问题
- VB在XP/2K 任务管理器的进程列表中隐藏当前进程
- 区块链 以太坊 solidity 如何比较2个字符串相等
- unity 3D入门
- 博弈论学习 | 第七章 Evolutionary Game Theory
- Zabbix结合Mojo-Webqq实现告警
- 厦门大学计算机软件学院,厦门大学软件学院研究生招生信息_厦门大学软件学院2019-研究生招生报名查询系统...
- PNG隐写入门赛 WP
- 单交换机配置vlan
- 企业微信信息服务器保存,企业微信接入
- C++ 笔试面试题 ~[有答案]
- 破解老程序员的迷茫病——JUST DO IT
- 洋酒销售系统的设计与实现(附源码+资料+论文+截图+数据库)
- iOS 高德地图开发详解
- 中国内地所有必胜客餐厅将停用塑料吸管;开元旗下开业酒店突破300家 | 美通企业日报...
热门文章
- 狼人杀c语言,微赛狼人杀正式版C位出道
- android 代码设置textview draw,Android 自定义气泡TextView
- 九章云极DataCanvas完成C轮融资:定义标准化AI基础架构未来
- python 无序列表中第k大元素_查询无序列表中第K小元素
- web程序前后台功能实现_好程序员web前端教程之JS继承实现方式解析
- 解决用Python对Sqlite进行数据更新比较慢的一种方法
- 操作系统之进程管理:16、管程
- (软件工程复习核心重点)第二章可行性研究-第一节:可行性研究基本介绍
- pthread_cleanup_push()/pthread_cleanup_pop()
- 1304. 和为零的N个唯一整数