JVM
jvm整体架构: .java文件通过javac编译成.class文件,通过JVM(从软件屏蔽不同操作系统在底层硬件指令上的区别)编译成机器码(不同操作系统对应相应的jdk版本)。
JVM分为类装载子系统,内存模型和执行引擎
当用java命令执行.class文件时,JVM首先通过类装载子系统,把字节码文件装载到内存区(一般装载到方法区),之后执行引擎执行内存区域的字节码文件。
方法区
方法区存放常量,静态变量和类元信息
注:在jdk1.8之后方法区叫元空间或者叫永久代,且1.8之后使用的是直接内存。是在jvm之外的一块内存
栈(又叫线程栈)
栈是一种数据结构,FILO,先进后出
存放局部变量,是每个线程独享
栈帧:在执行main方法时,会在当前栈中分配存放main方法局部变量的内存区。同时,假定main方法中存在compute方法,在执行到compute方法时,又会在栈中分配存放compute方法局部变量的内存区,该内存区与其他方法独立并列,称为栈帧。
栈帧中有局部变量表,操作数栈,动态链接,方法出口
标题程序计数器:
标题程序计数器中存放当前线程正在执行或将要执行的指令的内存地址。
程序计数器在执行第一条JVM指令时就已经有值,当执行完当前指令,执行引擎就会对程序计数器的值进行更新指向下一条JVM指令的地址。
分析字节码文件:
使用 javap -c Math.class > Math.txt 反编译字节码文件,输出的Math.txt文件
局部变量表会分配一块内存区域给a
方法出口
方法出口这一块内存区域存放的是方法执行完后,返回到线程中应该继续执行代码的位置
对象类型的变量,由指针指向堆中new出来的对象
动态链接
new出来的对象结构
一个对象new出来后,他的类型指针会指向类的元数据。当执行math.compute()时,会通过math的头指针找到类的元数据中的compute()方法对应jvm指令的地址,而这个地址就存放在动态链接中。
即动态链接中存放所有方法的指令码
本地方法栈:
存放本地方法中局部变量的就是本地方法栈。每个线程都有自己的本地方法栈。