天天看点

JVM——运行时常量池

“运行时常量池”  不等于 “常量池”。

运行时常量池 不是 class字节码中的常量池,运行时常量池是jvm在运行时,属于jvm内存区域中的一块内存,将class字节码文件中的常量池进行解析,然后再运行时常量池中进行相应的初步内存分配。

jvm如何执行一个代码?

加载字节码。java代码是由一个个类组成的,经过编译后,就形成了一个个class字节码文件,文件自然是存放在磁盘中的,要执行代码,就要先启动java虚拟机(jvm),jvm启动好了之后,从磁盘中将class字节码文件加载到内存中,具体加载到内存的哪个区域?jdk1.6版本以前,是加载到方法区(属于堆区),jdk1.8版本开始,是加载元数据区,元数据区不属于jvm运行时的内存区,已经独立出来了。jvm运行时的内存大小是有上限的(上限不是整个内存大小,是小于整个内存的),以前的方法区是jvm内存区的一部分,所以方法区就有限,因此class字节码(可以理解为程序)太大的话,方法区是容不下的(跑不起来),现在好了,存放在独立的元数据区了,这个元数据区大小是可以动态变化的,结合计算机的虚拟存储技术(内存+磁盘),理论上,元数据区可以扩展到 部分内存+磁盘空间  大小,就基本不用担心程序太大的问题了(除非内存+磁盘都不行)。

JVM——运行时常量池

动态解析字节码。jvm解析字节码的内容,根据这些内容,在jvm内存区域中的相应区域分配空间、初始化数据等等。

执行程序。根据程序的代码,获取指令、获取数据、执行指令、处理结果等等。

java语言中一切皆是对象,这个思想在jvm中也一样,都当做对象来看,为对象分配内存空间,然后直接使用的是这些对象的引用(类似指针),每一个class文件的常量池被封装为一个对象,解析到运行时常量池。

如何根据一个java类的class字节码文件,动态的将其常量池的信息动态分配或者初始化到运行时常量池中,一个类就有一个class字节码文件,就有一个常量池,所以运行时常量池其实是主要存放所有类的字节码文件中的常量池信息的(不是复制,而是根据常量池信息动态解析为运行时常量池中的内容)。

class文件的内容顺序是固定的,但是内容大小是不定的,常量池大小也是不定的,jvm是动态解析常量池的内容的,所以会动态分配运行时常量池的大小。