深入JVM内核——原理、诊断与优化

JVM启动流程

在这里插入图片描述

JVM基本结构

在这里插入图片描述

PC寄存器(程序计数器)

  1. 每个线程拥有一个PC寄存器
  2. 在线程创建时 创建
  3. 指向下一条指令的地址
  4. 执行本地方法时,PC的值为undefined

方法区

保存装载的类信息

  1. 类型的常量池
  2. 字段,方法信息
  3. 字段,方法信息

通常和永久区(Perm)关联在一起

Java堆

  1. 和程序开发密切相关
  2. 应用系统对象都保存在Java堆中
  3. 所有线程共享Java堆
  4. 对分代GC来说,堆也是分代的
  5. GC的主要工作区间
    在这里插入图片描述

Java栈

  1. 线程私有
  2. 栈由一系列帧组成(因此Java栈也叫做帧栈)
  3. 帧保存一个方法的局部变量、操作数栈、常量池指针
  4. 每一次方法调用创建一个帧,并压栈

Java栈 – 局部变量表 包含参数和局部变量

在这里插入图片描述

Java栈 – 函数调用组成帧栈

在这里插入图片描述

Java栈 – 操作数栈

Java没有寄存器,所有参数传递使用操作数栈
在这里插入图片描述

Java栈 – 栈上分配

  1. 小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上
  2. 直接分配在栈上,可以自动回收,减轻GC压力
  3. 大对象或者逃逸对象无法栈上分配在这里插入图片描述

栈、堆、方法区交互

在这里插入图片描述

内存模型

  1. 每一个线程有一个工作内存和主存独立
  2. 工作内存存放主存中变量的值的拷贝在这里插入图片描述
    在这里插入图片描述

volatile

在这里插入图片描述

可见性

  1. 一个线程修改了变量,其他线程可以立即知道
  2. 保证可见性的方法

volatile

  1. synchronized (unlock之前,写变量值回主存)
  2. final(一旦初始化完成,其他线程就可见)

有序性

  1. 在本线程内,操作都是有序的
  2. 在线程外观察,操作都是无序的。(指令重排 或 主内存同步延时)

指令重排

  1. 线程内串行语义
  2. 写后读 a = 1;b = a; 写一个变量之后,再读这个位置。
  3. 写后写 a = 1;a = 2; 写一个变量之后,再写这个变量。
  4. 读后写 a = b;b = 1; 读一个变量之后,再写这个变量
  5. 以上语句不可重排
  6. 编译器不考虑多线程间的语义
  7. 可重排: a=1;b=2;

指令重排 – 破坏线程间的有序性

在这里插入图片描述

指令重排 – 保证有序性的方法

在这里插入图片描述

指令重排的基本原则

  1. 程序顺序原则:一个线程内保证语义的串行性
  2. volatile规则:volatile变量的写,先发生于读
  3. 锁规则:解锁(unlock)必然发生在随后的加锁(lock)前
  4. 传递性:A先于B,B先于C 那么A必然先于C
  5. 线程的start方法先于它的每一个动作
  6. 线程的所有操作先于线程的终结(Thread.join())
  7. 线程的中断(interrupt())先于被中断线程的代码
  8. 对象的构造函数执行结束先于finalize()方法

解释运行

  1. 解释执行以解释方式运行字节码
  2. 解释执行的意思是:读一句执行一句

编译运行(JIT)

  1. 将字节码编译成机器码
  2. 直接执行机器码
  3. 运行时编译
  4. 编译后性能有数量级的提升
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值