1. jvm运行数据区
- 1 PC寄存器
1.1 每个线程都有一个pc寄存器
1.2 在线程创建时创建
1.3 指向下一条指令
1.4 指向本地方法时 pc的值为undefined
- 2 方法区
2.1 保存装载类的形象
2.1.1 类型的常量池
2.1.2 字段、方法信息
2.1.3 方法字节码
- 3 java堆
3.1 应用系统的所有对象保存在java堆中【但是不是所有对象都会分配到java堆中】
3.2 所有线程共享java堆
3.3 对于分代GC,堆也是分代的
3.4 应用系统的所有对象保存在java堆中
- 4 java栈
4.1 线程私有
4.2 栈由一系列帧组成
4.3 帧保存一个方法的局部变量、操作数栈、常量池指针
4.4 每次调用方法创建一个帧,并压栈
-
5 栈调用过程演示
- 6 栈上分配对象
//添加jvm 参数-server -Xmx10m -Xms10M -XX:+DoEscapeAnalysis 开启对象逃逸
public class T {
public static void main(String[] args) {
Long l = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
createObject();
}
System.out.println(System.currentTimeMillis() - l);
//开启 -XX:+DoEscapeAnalysis 17毫秒
//关闭 -XX:-DoEscapeAnalysis 10689毫秒
//可以看出来对象逃逸对性能的优化是非常巨大的
}
/**
* 如果开启-XX:+DoEscapeAnalysis 局部变量是分配到栈上
* 该变量随着方法的结束而销毁这样就大大的减少了GC的压
* 力,因为GC会回收堆上的对象
*/
static void createObject() {
byte[] b = new byte[2];
b[0] = 1;
}
}