jvm结构
2023-06-08 15:15:47 5 举报
JVM虚拟机架构和分解
作者其他创作
大纲/内容
静态变量
中间代码生成器
java栈
Eden->Survivor0/1->Old Area对象复制
线程共享
Y
一个JVM进程
方法区/元空间
新生代/新生区/年轻代(Young Generation Space)
方法区
Win版JVM
执行
application classloader
解释器
类装载器子系统Class Loader
JIT代码缓存
栈帧3
交互关系
Runtime Data Areas(单例)
Eden放得下?
类信息
java栈本地变量表
新对象申请
分析器
.Class
reference
线程A
6、Survivor0/1满了不会触发Young GC/Minor GC,只有Eden满了会触发Young GC/Minor GC,同时对Eden和Survivor0/1进行垃圾回收
java程序
prepare
Eden空间
=
加载信息到方法区
PC Registers
verify
是
堆(Heap)
当前栈帧
N
类装载子系统
栈顶
否
域信息
局部变量1实例
Stack Area
... ...
字节码文件
resolve
Full GC/Major GC
数组
TLAB分配
本地方法栈
类加载过程(装载,解析,初始化)
Linux版JVM
双亲委派机制
Class Loader Subsystem
Old放得下?
java栈java stack
系统类加载器application classloader
方法区(概念)永久代(PermGen实现)使用JVM内存
程序计数器program counter register
方法信息
变量关系
分配对象内存
JVM构造
内存区域
运行时常量池
栈帧1
本地方法栈Native method stack
堆
代码优化器
MethodArea
方法4
本地内存
运行时数据区(Runtime Data Area)
元空间Metaspace(实现)
NativeMethodStack
ThreadLocal
栈底
本地方法接口Native Method interface(JNI)
即时编译器JIT
1、java栈用于管理java方法的调用,本地方法栈用于管理本地方法的调用;2、线程私有3、与java栈拥有相同的特性,可固定大小,也可动态扩展;4、本地方法使用C实现5、在Native Method Stack中登记native方法,在Execute engine执行时加载本地方法库6、并不是所有的JVM都支持本地方法;7、和本地方法接口之间相互关联(JVM主图中)
堆、栈、方法区从线程共享的角度
字符串常量(String Table)
放置在Survivor0/1区
递进
方法区(概念)永久代PermGen(实现)使用JVM内存
java堆
Young GC/Minor GC
元空间/永久区/永久代(Meta Space)方法区
分配是否成功
JDK1.7
线程私有
向上委托
堆空间
StackOverFlowError
int
Loading
局部变量2实例
垃圾回收器
person
栈运行原理
线程共享的角度
引导类加载器bootstrap classloader
程序计数器
Linux操作系统
survivor1(to)
PC Registerfor thread1
PC Registerfor thread2
...
pc registerfor thread n
类型信息、运行时常量池、域(属性)、JIT编译后的代码缓存等
检查是否加载
类信息....
操作数栈(表达式栈)Operand Stack
自定义类加载器custom classloader
类型信息
更新PC计数器
95%的优化在堆
晋升老年代
方法2
自定义类加载器custom classloader
thread1
thread2
thread3
stack frame
LV OS DL RA
Linking
栈帧内部构成
1、一个Native Method就是一个java调用非java代码的接口,一个Native Method是这样一个方法,该方法的实现由非java语言实现;2、由native标识的方法,native可以与所有其他java标识符连接使用,abstract除外;
survivor0(from)
栈和程序计数器没有垃圾回收;程序计数器没有内存溢出,栈有可能会内存溢出;java栈和本地方法栈不存在GC,存在ERROR
对象实例
类及其方法的实现
extension classLoader
栈中能发多少栈帧,取决于栈帧的大小,栈帧的大小取决于栈内的局部变量表和操作数据等
对程序调试提供支持的信息
JDK1.8及以后
局部变量2
局部变量1
运行时常量池
Heap
超大对象
一些附加信息
方法区的演进细节
到对象类型数据的指针
动态链接(指向运行时常量池的方法引用)Dynamic Linking
Win操作系统
Survivor放得下?
1、CPU需要频繁的切换各个线程,这个时候切换回来以后,就需要知道接着从哪里开始执行;2、JVM字节码解释器需要通过PC寄存器的值,来明确下一条应该执行什么样的字节码指令;3、没有GC和内存溢出,线程独享,为了能够准确的记录各个线程正在执行的当前字节码指令地址4、线程私有
Young GC
1、Java虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机的启动而创建,随着虚拟机退出而销毁。2、另一些则与线程一一对应,这些与线程一一对应的数据区域,会随着线程的开始和结束而创建和销毁
Eden分配
1、new出的新对象首先放入Eden;2、当Eden填满了以后,程序又需要创建对象,Young GC/Minor GC将会对Eden区和Survivor0/1进行垃圾回收,将两个区域内的不再被对象引用的对象进行销毁,在加载新的对象到Eden区,将Eden原本存在未被销毁的对象转入Survivor0/1区,同时会有一个年龄计数器,记录这个对象存放的年龄,是否到阈值,如果还是不可回收,需要转入老年区3、如果再次经历垃圾回收,将Eden未被销毁的和Survivor0/1未被销毁的对象转入另外一个未被使用的Survivor0/1中,Survivor0和Survivor1总是有一块区域是空的;4、默认情况下如果Survivor0/1中的对象经过15次(对象存活阈值)垃圾回收,还没有销毁就转入老年区(Old Area),可以通过-XX:MaxTenuringThreshold=10 设置对象存活阈值;span style=\"font-size: inherit;\
方法返回地址(Return Address)
方法区Method Area
对象实例化
执行引擎execution engine
new Person();
伊甸园(Eden)
JDK中将String table调整到堆中,主要是因为永久代的回收率很低,在full GC的时候才会触发,而full GC在老年代、永久代空间不足的时候才会触发,导致String table的回收率不高,而我们开发中会有大量的字符串会被创建,回收率低,导致永久代空间不足,放到堆中能及时的回收内存。
initialization
虚拟机栈/java栈
double
方法1
方法3
局部变量表Local Variables
Person
栈、堆、方法实例对应关系
栈帧2
Byte Code
Class file
将reference入栈
类加载器机制
bootstrap classloader
对象实例数据
float
执行引擎
线程独享:程序计数器,java栈,本地方法栈线程共享:堆,堆外内存(永久代、元空间、代码缓存)
Mac操作系统
Mac版JVM
方法区(概念)
OutOfMemoryError:java heap space
JDK1.6
OutOfMemoryError:MetaSpace
对象分配过程-TLAB
堆、栈、方法区的交互关系
老年代/养老区/老年区(Old Gen)
编译
目标代码生成器
HeapArea
short
堆Heap
栈帧4
对象类型数据
对象存活超过阈值?
本地接口
1、一个类加载器收到了类加载的请求,他并不会自己先去加载,而是把请求委托给父类的加载器去加载。2、如果父类加载器还存在父类加载器,则进一步向上委托,依次递归,请求最终将达到顶层的启动类加载器。3、如果父类加载器可以完成类加载,就返回成功,如果完不成类加载任务,子加载器才会尝试自己去加载,这就是双亲委派机制4、避免类的重复加载,保护程序安全,保护核心api被随意篡改
5%的优化在方法区
扩展类加载器extension classLoader
0 条评论
下一页