jvm内存模型
2021-06-11 13:07:43 0 举报
jvm内存模型
作者其他创作
大纲/内容
1
对象共存
没有指针指向的对象--GC
public class Math{ public static final int initData = 666; public static User user = new User(); public int compute(){ int a=1; int b=2; int c=(a+b)*10; return c; } public static void main(String[] agrs){ Math math = new Math(); math.compute(); System.out.println(\"test\"); }}
加载Loading
2
4
Phone.class成员变量成员方法--
若是没有STW,线程结束(指针消失),对象依旧存在,无法准确判断垃圾
price:0 --- 999
private native void start0();native修饰的方法 C++实现,也需要内存空间
int a=1;int b=2;
执行引擎
java虚拟机
年轻代
.class:(类信息:类的版本、字段、方法、接口、构造函数等描述信息 )+常量池表:字面量(常量值)+符号引用
class PhoneDemo{ psvm(){ Phone p = new Phone(); p.brand = \"白色\"; p.price = 999; p.call(\"张三\"); }}
虚拟机本身方法存储
调用方式
Eden(8/10)
栈中
属性/方法
call(String name)
0
user.class
静态变量
栈(线程)VM Stack
方法共存
栈中添加10
0x001
minor gc
初始化
程序计数器
重复赋值C
方法区(元空间)Method Area
堆中
新的垃圾回收线程
堆Heap
brand:null--“白色”
线程2
对整个堆内存gc
Math.class
compute()-栈帧
math
GC Roots
jVM调优:STW(Stop the Work)
线程私有
方法出口
s1(1/10)
垃圾回收线程
10
当运行到p.call(\"张三\");时通过栈p找到堆中存放的方法区的地址,从而找到方法区中Phone.class中的方法。然后将call方法加载到栈内存,执行完call从栈中去除。
本地方法库
所有对象实例和数组
运 行 时 数 据 区
3
Eden内存满时
堆
方法内部使用
survivor幸存者
符号引用转换成直接引用,存放方法区中方法的内存地址
String.intern()运行时字符串加入字符串常量池(1.6值,1.7堆内的字符串的引用)
成员变量、局部变量、静态变量的区别
类中方法外
方法中、形参
main()-栈帧
栈(线程)
程序当前执行的位置,线程正在运行的行号
Phone p ----0x001
Class
动态链接
30
user对象
FILO
3.3将3放到操作数栈中
本地方法栈
b=2
局部变量表
iadd:1+2=3
5
用于线程切换时标识
运行时常量池和字符串常量池:1.7以后在堆中
控制流程的指示器
取出1和2放在操作数栈中
别名
它是程序控制流的指示器。 分支、 循环、 跳转、 异常处理、 线程恢复等基础功能
解析Resolution
new Phone()时在堆中开辟空间地址为0x001,找到Phone的class文件,将变量和方法地址放在堆中
a=1
老年代(2/3)
类名调用,对象调用
元空间的本质和永久代类似,都是对JVM规范中方法区的实现。
类装载子系统classLoader
方法区
局部变量
JVM调优工具Arthas(阿里开源)
1.栈中添加1
对象调用
OOM内存溢出
虚拟机栈描述的是Java方法执行的线程内存模型:1. 每个方法被执行的时候, Java虚拟机都会同步创建一个栈帧(Stack Frame) 2.栈帧:用于存储局部变量表、 操作数栈、 动态连接、 方法出口等信息。
new Phone()
用于存储已被虚拟机加载的:
栈
程序从main方法进入,运行到Phone p 时在栈中开辟空间
一个对象的执行过程
3.1取出1和2
操作数栈
1. .class文件存放在方法区中,而堆内存中具体对象,成员方法引用(十六进制)指向方法区中存在的方法代码。2. 每当方法被执行就会被加载到栈中(压栈),方法执行完毕就直接弹栈,main方法是先被加载,所以在栈底,最后才释放main方法。
main线程
本地方法栈Native Method
--
minor少数的
线程公有
通过修改执行下条字节码指令
程序计数器Programma Counter Register
javac Math.java
c=30
javac Math.class
2.取出操作数栈中1和2放到局部变量表中
局部变量表:(存放了编译期可知的)1.基本数据类型2.对象的引用3.returnAddress
执行
继续运行,p.brand = \"白色\";,通过栈p找到堆中的brand,将null修改成白色
类中、方法外
常量(池)
元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小
...
main方法
用户点击提交,添加购物车等都属于用户进程
full gc
实例变量
类变量
有指针指向的对象,回收一次+1
成员变量
类共存
int c=(a+b)*10;
3.2求和
class Phone{ String brand; int price; public void call(String name){ sop(name); }}
初始化initialization
默认
Java 类的加载过程:
最后,main方法结束。
元空间存储在本地
···
老年代满了
存储位置
准备Preparation
Survivor区
s0(1/10)
链接Linking
PhoneDemo.classmain方法
imul:3*10=30
可达性分析算法
0--this
存放对象的内存地址
字节码执行引擎
本地库接口
验证Loading
编译器生成的字面量和符号引用
1、2
3.将1赋值给a,2赋值b
15
生命周期
定义位置
jdk1.8以后取消方法区,替换为元空间
java API
先定义.赋值使用
回收整个年轻代
回收15次后进入老年代
gc线程属于后台进程,执行时会将用户进程停止
类信息(.class+ClassLoader)
0 条评论
回复 删除
下一页