.class文件
我们都知道,class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池(constant pool table),用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)。
字面量就是我们所说的常量概念,如文本字符串、被声明为final的常量值等。
符号引用是一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可(它与直接引用区分一下,直接引用一般是指向方法区的本地指针,相对偏移量或是一个能间接定位到目标的句柄)。一般包括下面三类常量:
类和接口的全限定名
字段的名称和描述符
方法的名称和描述符
方法区
存放对应类的Class类的信息,Class类对象在堆里面
运行时常量池在方法区里:.class文件经过classloader加载、连接、初始化,而连接又包括验证、准备、解析三个阶段到方法区中,就会把class常量池的内容存放到运行时常量池中(符号引用->直接引用,静态变量初始化),并且方法区把字符串放到了字符串常量池中(在堆中)
程序计数器PC
我们知道,被加载到jvm的类对象是我们写的.java文件被编译之后的.class文件。
在编译过后会将我们的代码编译成计算机能读懂的字节码。而这个.calss文件就是,就是我们代码编译好的字节码了。
加载到内存以后,字节码执行引擎就开始工作了。去执行我们编译出来的代码指令,此时问题来了,我们是不是需要一块内存空间来记录我们字节码执行引擎目前执行到了哪行代码?这一块特殊的内存区域就是“程序计数器”,又因为不同线程导致线程切换所以必须配备独立的PC
java栈
java代码在执行的时候,一定是某个线程来执行某个方法中的代码。
当线程执行到某个方法的时候,如果这个方法有局部变量,那么就需要一块区域来存放局部变量的数据信息。这个区域就叫做java虚拟机栈。
每一个线程都有一个自己的java虚拟机栈,比如说当执行main方法的时候就会有一个main线程,用来存放main方法中定义的局部变量
堆
存放所有实例化的对象,字符常量池也保存再堆里
JVM最终模型:
参考:https://www.cnblogs.com/zhxiansheng/p/11185840.html#autoid-4-0-0