jvm流程图
2022-09-09 14:31:31 0 举报
jvm结构流程图及多线程
作者其他创作
大纲/内容
程序计数器
加载(Loding)1、通过一个类的全限定名(比如com.zxhx.test.HelloWorld.class)来获取其定义的二进制字节流。2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。3、在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口。链接(Linking)1、验证(Verification):为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求文件格式验证、元数据验证、字节码验证和符号引用验证2、准备:正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间3、解析:指虚拟机将常量池中的符号引用替换为直接引用的过程初始化如果该类具有父类就进行对父类进行初始化,执行其静态代码块和静态初始化成员变量。调用类构造器< clinit >()方法,该方法不需定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来,如果类中没有静态变量或者静态代码块,则不会出现<clinit>()方法
form(1/10)
3
动态链接
1、定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类本数据类型、对象引用(reference),以及ReturnAddress类型2、由于局部变量表是建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题3、如果数据是在内部产生,内部消亡的,则是线程安全的;不是内部产生,或者作为返回值返回的(生命周期没有结束)就不是安全的
(1) 逻辑上:堆=新生+老年+永久或者元空间(2)物理上:堆=新生+老年
验证Verification
系统调度
to(1/10)
老年代2/3
Thread.start()
初始(NEW)
方法区(元空间)
多线程状态
1、存放该方法的pc寄存器的值2、方法正常退出时,调用者的pc寄存器的值作为返回地址,即调用该方法的指令的下一条指令的地址。3、而通过异常退出的,返回地址是要通过异常表来确定,栈帧中一般不会保存这部分信息
虚拟机栈
初始化Initialization
Old
卸载Unloading
Object.wait()Object.join()LockSupport.park()
加载目录
新生代1/3
常量池
自定义加载器加载路径下未找到抛出ClassNotFound异常
6
链接(Linking)
常量池中主要存放两大类常量:字面量和符号引用,字面量很好理解就是我们java语言中的字符串、final定义的常量值等;符号引用主要包含下面三类常量:1、类和接口的全限定名(Fully Qualified Name)2、字段的名称和描述符(Descriptor)3、方法的名称和描述符
就绪(Ready)
使用Using
本地方法栈
Class类信息
1、每个方法在执行的同时都会创建一个栈帧并随着方法结束而销毁2、虚拟机栈会出现StackOverflowError,但是不会出现GC,因为只有进栈出栈,出栈的过程就相当于GC
扩展类加载器
1、 Eden 区Java 新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老年代)。当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行一次垃圾回收。2、ServivorFrom上一次 GC 的幸存者,作为这一次 GC 的被扫描者。3、ServivorTo保留了一次 MinorGC 过程中的幸存者。4、 MinorGC 的过程(复制->清空->互换)MinorGC 采用复制算法。(1)eden、servicorFrom 复制到 ServicorTo,年龄+1(2)清空 eden、servicorFrom(3)ServicorTo 和 ServicorFrom 互换5、老年代主要存放应用程序中生命周期长的内存对象老年代的对象比较稳定,所以 MajorGC 不会频繁执行。在进行 MajorGC 前一般都先进行了一次 MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。MajorGC 采用标记清除算法
1、 java7之前,方法区位于永久代(PermGen),永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变;2、 java7中,static变量从永久代移到堆中;3、 java8中,取消永久代,方法存放于元空间(Metaspace),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中
自定义类加载器1
等待进入synchronized方法等待进入synchronized块
执行引擎
class文件
。。。。。。
4
超时等待(TIMED_WAITING)
ExtClassLoader加载路径下未找到交由AppClassLoader去加载
系统/应用类加载器
栈帧2
1
Meta Space(元空间)
启动类/跟类加载器
运行时数据区
Object.notify()Object.notifyAll()LockSupport.unpark(Thread)超时时间到
yield()系统调度
即时编译器
阻塞(BLOCKED)
5
CLASSPATH路径下指定,如未设置则为应用程序当前路径
AppClassLoader加载路径下未找到交由自定义加载去加载
局部变量表
类加载器子系统
本地方法库
指向运行时常量池中该栈帧所属方法的引用
运行(RUNNABLE)
终止(TERMINATED)
实例化
JVM 通过双亲委派模型进行类的加载,当然我们也可以通过继承 java.lang.ClassLoader实现自定义的类加载器。双亲委派:当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,只有当父类加载器反馈自己无法完成这个请求的时候,子类加载器才会尝试自己去加载。好处:使用不同的类加载器最终得到的都是同样一个 Object 对象
自定义类加载器2
%JAVA_HOME%/jre/lib/ext路径下的jar包
2
方法元信息
类加载器
准备Preparation
Esen 伊甸园(8/10)
%JAVA_HOME%/lib路径下的jar包
运行中(Running)
本地库接口
一些附加信息
Object.notify()Object.notifyAll()LockSupport.unpark(Thread)
垃圾收集
BootStrap加载路径下未找到目标Class交由ExtClassLoader去加载
栈帧1
执行完成
解析Resolution
堆(Heap)
7
等待(WAITING)
主要用于保存计算过程中的中间结果,同时作为计算过程中变量临时的存储空间
加载用户指定目录下的Class
获取到锁
委托
加载Loading
挂载
操作数栈
Thread.sleep(long)Object.wait(long)Thread.join(long)LockSupport.packNanos()LockSupport.packUntil()
方法返回地址
堆
收藏
收藏
0 条评论
下一页