JVM原理
2022-04-11 17:32:40 0 举报
Java JVM原理图示
作者其他创作
大纲/内容
Java源代码(.java文件)
Local Variable Array
Runtime Data Areas
字节码本地或网络
Java虚拟机
Method Area
硬件
当运行java虚拟机时,这个类加载器被创建,它加载一些基本的java API,包括Object这个类。需要注意的是,这个类加载器不是用java语言写的,而是用C/C++写的。负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
Preparing
User Defined Class Loader
字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。
Linking
Resolving
Bootstrap Class Loader
Java编译环境
运行期系统
Java栈
执行引擎Execution Engine
Java类库
类加载器层级结构
运行一个JVM实例时,系统将分配一块内存区域(大小可以设置),这块区域由JVM管理。这块内存中分出一块用来存储运行时数据,称为运行数据区域运行数据区域可以划分为6大块:Java栈、程序计数寄存器(PC寄存器)、本地方法栈(Native Method Stack)、Java堆、方法区域、运行常量池(Runtime Constant Pool)。运行常量池本应该属于方法区,但是由于其重要性,JVM规范将其独立出来说明。PC寄存器、Java栈、本地方法栈线程独立PC计数器:每一个线程都拥有一个PC计数器,当线程启动(start)时,PC计数器被创建,这个计数器存放当前正在被执行的字节码指令(JVM指令)的地址。Java栈Java栈也是每个线程单独拥有,线程启动时创建。这个栈中存放着一系列的栈帧(Stack Frame),JVM只能进行压入(Push)和弹出(Pop)栈帧这两种操作。每当调用一个方法时,JVM就往栈里压入一个栈帧,方法结束返回时弹出栈帧。如果方法执行时出现异常,可以调用printStackTrace等方法来查看栈的情况。每个栈帧包含三个部分:本地变量数组,操作数栈,方法所属类的常量池引用。局部(本地)变量数组:局部(本地)变量数组中,从0开始按顺序存放方法所属对象的引用、传递给方法的参数、局部变量。操作数栈:操作数栈中存放方法执行时的一些中间变量,JVM在执行方法时压入或者弹出这些变量。其实,操作数栈是方法真正工作的地方,执行方法时,局部变量数组与操作数栈根据方法定义进行数据交换。栈帧中数据引用:除了局部变量数组和操作数栈之外,栈帧还需要一个常量池的引用。当JVM执行到需要常量池的数据时,就是通过这个引用来访问常量池的。栈帧中的数据还要负责处理方法的返回和异常。如果通过return返回,则将该方法的栈帧从Java栈中弹出。如果方法有返回值,则将返回值压入到调用该方法的方法的操作数栈中。另外,数据区中还保存中该方法可能的异常表的引用。本地方法栈当程序通过JNI(Java Native Interface)调用本地方法(如C或者C++代码)时,就根据本地方法的语言类型建立相应的栈。方法区域方法区域是一个JVM实例中的所有线程共享的,当启动一个JVM实例时,方法区域被创建。它用于存运行放常量池、有关域和方法的信息、静态变量、类和方法的字节码。不同的JVM实现方式在实现方法区域的时候会有所区别。Oracle的HotSpot称之为永久区域(Permanent Area)或者永久代(Permanent Generation)。运行常量池这个区域存放类和接口的常量,除此之外,它还存放方法和域的所有引用。当一个方法或者域被引用的时候,JVM就通过运行常量池中的这些引用来查找方法和域在内存中的的实际地址。堆(Heap)堆中存放的是程序创建的对象或者实例。这个区域对JVM的性能影响很大。垃圾回收机制处理的正是这一块内存区域。所以,类加载器加载其实就是根据编译后的Class文件,将java字节码载入JVM内存,并完成对运行数据处于的初始化工作,供执行引擎执行。基础数据类型直接在栈空间分配,方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收。引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量 。方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完成后从栈空间回收。局部变量new出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收。方法调用时传入的literal参数,先在栈空间分配,在方法调用完成后从栈空间收回。字符串常量、static在DATA区域分配,this在堆空间分配。数组既在栈空间分配数组名称,又在堆空间分配数组实际的大小。
这个加载器加载出了基本API之外的一些拓展类,包括一些与安全性能相关的类负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
即时编译器
Java解释器
Native Method Stack
Runtime Constant Pool
它加载应用程序中的类,也就是在你的classpath中配置的类。负责记载classpath中指定的jar包及目录中class
类装载器字节码的验证
自顶向下尝试加载类
Thread
这是开发人员通过拓展ClassLoader类定义的自定义加载器,加载程序员定义的一些类。属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
JVM Stack
类加载完毕后JVM继续工作
操作系统
System Class Loader
Java运行期环境
PC Register
Verifying
Operand Stack
Extension Class Loader
Reference to Constant Pool
Java字节码
Java编译器
自底向上检查是否已经加载
Stack Frame
loading
Heap
Initializing
执行引擎
0 条评论
回复 删除
下一页