JVM基本结构图
- PC寄存器
1 | 1、每个线程拥有一个PC寄存器 |
方法区
1 | 1、保存装载的类信息 |
1、所有线程共享Java堆
2、分新生代、老年代
3、新生代分s0 s1区
4、Java堆和程序数据密切相关1
2
3> 在绝大多数情况下,对象首先分配在eden区,在一次新生代回收之后,如果对象还存活,则进入s0或者s1,每经过一次新生代回收,对象如果存活,它的年龄就会加1。当对象的年龄达到一定条件后,就会被认为是老年对象,从而进入老年代。
> GC分代收集
package com.jvm;
public class SimpleHeap {
private int id;
public SimpleHeap(int id){
this.id = id;
}
public void show(){
System.out.println(“My id is “+id);
}
public static void main(String[] args) {
SimpleHeap s1 = new SimpleHeap(1);
SimpleHeap s2 = new SimpleHeap(2);
s1.show();
s2.show();
}
}
1 | ![Markdown](http://i2.bvimg.com/634857/f410cf1a4a78d225.png) |
1、Java栈和线程执行相关
2、线程私有
3、先进后出
4、栈由一系列帧组成
5、静态方法和非静态方法 第一个局部变量的槽位不同,非静态第一个槽位是this的引用1
2
3
4
5
6
7
8
9
10- 局部变量表
> 局部变量表是栈帧的重要组成部分之一。它用于保存函数的参数以及局部变量,局部变量表中的变量只在当前函数调用中有效,当函数调用结束,随着函数栈帧的弹出销毁,局部变量表也会随之销毁。
> 由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量很多,会使得局部变量表膨胀,从而每一次函数调用就会占用更多的栈空间,最终导致函数的嵌套调用次数减少。
- 操作数栈
- Java栈 栈上分配
1、小对象、栈上分配
2、大对象或者逃逸对象无法栈上分配
3、栈上分配,使用完毕,可以自动回收,减轻GC的压力1
### 内存模型
1、每一个线程有一个工作内存和主内存独立
2、工作内存存放主存中的变量的值和拷贝1
### 可见性
1、volatile关键字修饰
2、synchronize
3、final(一旦初始化完成,其他线程可见)1
2
### 有序性
1、一个线程内会有指令重排
2、synchronize修饰了函数,可以保证指一个线程内令重排后,其他线程读取到的值是最新的1
2
### 指令重排
1、程序顺序规则:首先保存程序顺序的前提下会出现指令重排
a=4;b= a+1; 这种情况不会指令重排
一个线程内保证语义的串行性
2、volatile规则:volatile变量的写,先发生于读
3、锁规则:解锁必然先发生在随后的加锁(lock)💰`