# 对象初始化
类静态初始化方法
<clinit>
:不能被直接调用,而是由new,getstatic, put static, invokestatic这些指令触发(创建类实例,访问静态字段,调用静态方法)创建实例对象:
// 只是创建对象,不调用构造函数 new #2 // 复制栈顶的值,并将复制的值压入栈 dup // 用来调用特殊方法,这里是调用构造函数 invokeespecial #3 // Method "<init>":()V
1
2
3
4
5
6
# JVM内存结构
- 线程栈:
保存调用链上正在执行的所有方法的局部变量,每个线程只能访问自己的,不能访问和看见其它线程的局部变量
- 方法栈
- 调用栈
- 堆内存 包含创建的所有对象,也包括包装类型(Byte,Integer,Long等)
- 原生类型局部变量,保存在线程栈上
- 对象引用,则栈中局部变量中保存着对象的引用地址,对象内容保存在堆中
- 对象的成员变量和对象一起保存在堆中
- 类的静态变量和类定义保存在堆中
栈:每启动一个线程,jvm就会在栈空间为它分配对应的线程栈(-Xss1m定义),线程执行过程中,每执行到一个方法,就会创建相应的栈帧。栈帧包括返回值、局部变量、给指令用的操作数栈,以及class指针(指向这个其对应的类的方法,非堆中的Class对象)
堆:堆分为非堆和堆两部分。非堆一般不归GC管理,包括Metaspace(meta区)Compreessed Class Space,存放s信息,与Metaspace朋交叉。Code Cache存放jIT编译器编译后的本地机器代码
TLAB:预分配线程对象空间
# 指令运行
流水线方式,为充分利用流水线资源实现了“指令乱序”,内部调度时,打乱执行顺序执行,但会保证程序结果等价和正确。
# 内存模型
- 读屏障
- 写屏障
屏障用于屏蔽cpu的指令重排序功能,cpu看到这些指令时,保证这个指令前后的相应操作不会被打乱
- #LoadLoad:屏障前面的Load指令一定要先执行完,才可执行后面的Load指令
- #StoreStore:变量写入严格保障顺序,需要在变量写入的Stoe指令之间加入
- #LoadStore:短暂屏蔽指令重排序功能
- #StoreLoad:确保之前的Store指令对其它处理可见,在后面执行的Load指令都能拿到最新的值