jvm详细架构
2021-12-01 14:41:55 0 举报
jvm详细架构
作者其他创作
大纲/内容
为类变量分配内存,并设置该类变量的默认初始值,即0值这里font color=\"#ff0000\
执行引擎Execution Engine
本地方法接口Native Method interface
Heap Area
详细图
JIT Compiler
本地方法库
Thread 1
Thead 2
Thead 3
Stack Frame
Stack Frame(LV OS Dl RA)
存放调用该方法的pc寄存器的值一个方法的结束,有两种方式 正常执行完成 出现未处理的异常,非正常退出无论通过哪种方式推出,在方法退出后都返回到该方法被调用的位置,方法正常退出时,调用者的pc计数器的值作为返回地址,即调用该方法的指令的下一条指令地址。而通过异常退出的,返回地址时要通过异常表来确定,栈帧一般不会保存这部分信息本质上,方法的退出就是当前栈帧出栈的过程,此时,需要恢复上层方法的局部变量表、操作数栈、将返回值压入调用者栈帧的操作数栈、设置pc寄存器值等,让调用者方法继续执行下去正常完成出口和异常完成出口的区别在于:通过异常完成出口退出的不会给他的上层调用者产生任何的返回值
操作数栈(Operand Stack)
S0
初始化阶段就是执行类构造器方法<clinit>()的过程此方法不需定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来构造器方法中指令按语句在源文件中出现的顺序执行<clinit>() 不同于类的构造器若该类具有父类,jvm会保证子类的<clinit>() 执行前,父类的<clinit>()已经执行完毕虚拟机必须保证一个类的<clinit>() 方法在多线程下被同步加锁
简图
TargetCodeGenerator
S1
老年代(Tenure/Old generation)
Interpreter
《java虚拟机规范》中明确说明:“尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩”。所以方法区可以看作是一块独立于Java堆的内存空间span style=\
Loading
JIT代码缓存
Extension ClassLoader
Java Virtual Machine Stack
方法区
Class Loader SubSystem
方法区Method Area
Resolve
Intermediate CodeGenerator
运行时常量池
BootStrap ClassLoader
方法信息
Garbage Collection
Application(System) ClassLoader
Native Method Interface(JNI)
Class file
运行时数据区(Runtime Data Area)
Java Virtual Machine Stack Area
局部变量表(Local Variables)
Native Method Library
静态变量(jdk7以及之后版本存储在堆中)
Execution Engine
成员变量。jvm必须在方法区中保存类型的所有域的相关信息以及域的声明顺序域的相关信息包括:域名称、域类型、域修饰符
定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用,以及returnAddress类型由于局部变量表是建立在线程栈上,是线程私有的数据,因此不存在线程安全问题局部变量表所需的容量大小是在编译器确定下来的,并保存在方法的code属性maximum local variables 数据项中,在方法运行期间是不会改变局部变量表的大小的方法嵌套调用的次数是由栈的大小决定。一般来说,栈越大,方法嵌套调用次数越多局部变量表中的变量只在当前方法调用中有效。当方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁局部变量表,最基本的存储单元是Slot(变量槽)局部变量表中存放编译器可知的font color=\"#000000\
PC Register for thread1
PC Register for thread2
PC Register for thread3
.....
PC Register for thread n
jdk1.6以及之前
font color=\"#ff0000\
jdk1.7
有永久代,但已经逐步“去永久代”,字符串常量池(方便回收,String创建太频繁)、静态变量移除,保存在堆中
jdk1.8
无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但字符串常量池、静态变量仍在堆
Verify
Method Area
Prepare
Native Method Stack
伊甸园(Eden)
类加载子系统Class Loader SubSystem
栈帧(Stack Frame)
Linking
Initialization
将常量池内的符号引用(字节码中的#1 #2 等)转换为直接引用的过程
操作数栈,在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈(push)/出栈(pop)。某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈。使用它们后再把结果压入栈。比如:执行复制、交换、求和等操作操作数栈所需的最大长度在编译器就已经定义好了栈中的任何一个元素都可以是任意的java数据类型。 32bit的类型占用一个栈单位深度 64bit的类型占用两个栈单位深度如果被调用的方法带有返回值的话,其返回值将会被压入当前栈帧的操作数栈中java虚拟机的解释引擎是基于栈的执行引擎,其中的栈指的就是操作数栈
类型信息
动态链接(Dynamic Linking)
Runtime Data Area
一个jvm实例只存在一个堆内存,堆也是java内存管理的核心区域《java虚拟机规范》规定,堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的所有线程共享java堆,但是这里还可以划分线程私有的缓冲区TlAB(Thread Local Allocation Buffer)jvm为每个线程分配了一个私有的缓冲区域,它包含在Eden空间内(每个线程私有,起到数据隔离的作用)尽管不是所有的对象实例都能在TLAB中成功分配内存,但jvm确实将TLAB作为内存分配的首选。默认情况下TLAB占用的空间内存非常小,仅占用整个Eden空间的1%font color=\"#ff0000\
永久代(Permanent generation)jdk1.8改为元数据区(Meta Space)
运行时常量池是方法区的一部分。常量池表是Class文件的一部分,用于存放编译器生成的各种字面量和符号引用。这部分内容将在类加载后存放到方法区的运行时常量池中字节码文件中的常量池加载进内存后就称为运行时常量池常量池可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型
方法返回地址(Return Address)
堆Heap Area
本地方法栈Native Method Stack
Class Files
域信息
程序计数器Program Counter Register
指向运行时常量池的方法引用。在java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在class文件的常量池里。动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用
一些附加信息
年轻代(young/New generation)
虚拟机栈Java Virtual Machine Stack
PC Counter Register
Profiler
Code Optimizer
0 条评论
下一页