JVM整体结构及内存模型
2022-10-01 20:28:15 3 举报
JVM整体结构及内存模型
作者其他创作
大纲/内容
内存地址
对象头的指针Klass pointer指向元数据信息
运行时数据区(内存模型) JDK8
main线程
方法出口
程序计数器(PC寄存器)
java Math.class
静态变量user在堆里的内存地址
s1(1/10)
this
装载类子系统
a=1
jvm参数设置-Xss:每个线程的栈大小-Xms:设置堆的初始可用大小,默认物理内存的1/64 -Xmx:设置堆的最大可用大小,默认物理内存的1/4-Xmn:新生代大小-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。关于元空间的JVM参数有两个:-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N
STW
堆-Xms-Xmx
OOM
堆
user
执行
b=2
局部变量表
除了回收堆,还会回收元空间里的无用的类也就是类元信息。无用的类要满足以下三个条件:1.该类所有的实例对象都被回收,java堆中不存在该类的任何实例、及堆里对象的对象头指针都不指向这个方法区里的类元信息2.加载该类的类加载器被回收,比如jsp类加载器3.该类对应的java.lang.Class对象存在堆里的这个对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
直接内存(内存条)
字节码执行引擎
FIFO 栈(线程)
蓝色私有,紫色共享
动态水平自动伸缩
程序计数器
Survivor 区
Math.class呈现形式是元数据信息
栈(线程)
-XX:MaxMetaspaceSize
Class<? extends Math> mathCLass=math.getClass()存放的是类装载完后,jvm提供给开发人员访问类的一些信息,比如通过反射, 获取类的方法等而jvm内部拿类信息用的是对象头里类型指针获取方法区里的类元信息
由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大,对于8G物理内存的机器来说,一般我会将这两个值都设置为256M。
s0(1/10)
每执行完一行代码修改程序计数器的值
full gc
操作数栈
默认15次会放入老年代
动态链接
JVM虚拟机
本地方法栈(运行本地方法所需要的内存空间)
方法区(元空间)常量+静态变量+类信息+即时编译器编译后的代码缓存
2
本地方法栈
compute()-栈帧
设置元空间最大值, 默认是-1, 即不限制, 或者说只受限于本地内存大小。
math.getClass()
-Xss设置越小count值越小,说明一个线程栈里能分配的栈帧就越少,但是对JVM整体来说能开启的线程数会更多
Eden(8/10)
minor gc
c=30
存放的是math对象在堆里的内存地址
新生代 -Xmn
指定元空间触发Fullgc的初始阈值(元空间无固定初始大小), 以字节为单位,默认是21M左右,达到该值就会触发full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间, 那么在不超过-XX:MaxMetaspaceSize(如果设置了的话) 的情况下, 适当提高该值。
老年代(2/3)
栈(线程1)-Xss
main()-栈帧
先进后出符合程序的执行顺序
-XX:MetaspaceSize
math
0 条评论
回复 删除
下一页