jvm-java内存区域


在这里插入图片描述

jvm内存模型

运行时数据区域

  • 程序计数器
    它是一块较小的内存空间,它可以看作是当前线程所执行的字节码行号指示器。(线程私有的

问题:使用PC寄存器存储字节码指令地址有什么用?为什么使用PC寄存器记录当前线程的执行地址?
因为CPU需要不断切换各个线程,我们需要知道切换回来后从哪里开始
JVM的字节码解释器需要通过改变PC寄存器的值来明确吓一跳应该执行什么字节码指令。

  • java虚拟机栈
    线程私有
    虚拟机栈是描述java方法执行的线程内存模型,每一个方法被执行的时候,java虚拟机都会创建一个栈帧用于存放局部变量表 ,操作数栈,动态链接,方法出口。每一个方法被调用到执行完毕的过程,就对应着一个栈帧进栈到出栈的过程。

  • 本地方法栈
    作用和java虚拟机栈类似,只是服务于native方法

  • java堆
    线程共享 存放对象实例的。jvm规范上对java堆的描述是:“所有的对象实例以及数组都应当在堆上分配”但是现在已经不是那么绝对了。在这里插入图片描述

  • 方法区
    方法区与java堆一样,是线程共享它用于存储已被虚拟机加载的类型信息,常量,静态变量,也就是编译器编译后的代码缓存等数据。
    jdk8 之前,方法区的实现是永久代。这种实现会使java应用更容易OOM,因为有-XX:MaxPermSize 上限。
    jdk8之后,改为本地内存来实现,使用元空间。

  • 运行时常量池
    运行时常量池是方法区的一部分。Class文件中除了有类的版本,字段,方法,接口等描述外,还有常量池。用于存放编译器生成的各种字面量与符号引用(连接后 会转为直接引用),后面这部分加载后放到方法区的运行时常量池。

HotSpot虚拟机对象

  • 对象的创建
  1. 遇到字节码new指令时,先去检查参数是否能在常量池中定位到一个类的符号引用,并且检查引用类是否被加载,解析,初始化。
  2. 在对象已经被初始化之后,取到对象长度,先询问TLAB能否分配,如果不可以就在Eden中分配,(使用CAS 分配空间)
  3. 虚拟机对对象进行必要的设置,类信息。对象哈希码,对象GC分代年龄等等。
  4. java编译器在new 的时候会接着执行()方法,进行初始化。
  • 对象的内存布局
    对象在堆内存中的布局可以分为三个部分:对象头,实例数据和对
    齐填充。
    • 对象头
      1. 用于储存对象自身运行时的诗句,例如哈希码,GC分代年龄,锁状态标志,线程持有锁,偏向线程id,偏向时间戳。
      2. 类型指针,也就是指向它的类型元数据的指针。
    • 实例数据
      程序里定义的各种类型的字段内容。
    • 对齐填充
      占位符的作用
  • 对象的访问定位
    • 第一种:句柄访问
      java堆中将会划分出一块内存作为句柄池,reference中存储的就是句柄地址,句柄中包含对象实例数据的指针和对象类型数据的指针
      优点:对象被移动的时候只需要改变句柄实例数据指针,reference不需要修改。
    • 第二种:直接指针访问
      reference中储存的就是对象实例数据地址,对象实例中就需要指向对象类型数据的指针(HotSpot 默认这种)
      优点:速度快。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值