美文网首页JVM学习
深入JVM9 运行时数据区

深入JVM9 运行时数据区

作者: 香沙小熊 | 来源:发表于2021-02-26 11:57 被阅读0次

    1. 运行时数据区

    包括:PC 寄存器、Java虚拟机栈、Java堆、方法区、运行时常量池、本地方法栈

    1.1 PC(Program Counter)寄存器(线程私有)

    程序计数器(线程私有):就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码)由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。
    1:每个线程拥有一个PC寄存器,是线程私有的,用来存储指向下一条指令的地址
    2:在创建线程的时候,创建相应的PC寄存器
    3:执行本地方法时,PC寄存器的值为underfined
    4:是一块较小的内存空间,是唯一一个在JVM规范中没有规定OutOfMemoryError的内存区域

    1.2 Java虚拟机栈(线程私有)

    Java线程执行方法的内存模型,一个线程对应一个栈,每个方法在执行的同时都会创建一个栈帧(用于存储局部变量表,操作数栈,动态链接,方法出口等信息)不存在垃圾回收问题,只要线程一结束该栈就释放,生命周期和线程一致

    • 局部变量表存放了编译期可知的各种基本数据类型和引用类型,每个slot存放32位的数据,long、double占两个槽位
    • 栈的优点: 存取速度比堆快,仅次于寄存器
    • 栈的缺点:存在栈中的数据大小、生存期是在编译期决定的,缺乏灵活性
    image.png
    1.3本地方法栈(线程私有)

    登记native方法,在Execution Engine执行时加载本地方法库

    1.4. Java堆内存(线程共享)

    Java堆用来存放应用系统创建的对象和数组,所有线程共享Java堆
    Java堆是在运行期动态分配内存的大小,自动进行垃圾回收

    GC主要就管理堆空间,堆分代GC来说,堆也是分代的
    堆的优点: 运行期动态分配内存大小,自动进行垃圾回收
    堆的缺点: 效率相对较慢

    1.5 方法区(线程共享)

    类的所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,静态变量+常量+类信息(构造方法/接口定义)+运行时常量池都存在方法区中,虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。

    • 通常和元空间关联在一起,但具体的跟JVM实现和版本有关
    1.6运行时常量池:

    是Class文件中每个类或接口的常量池表,在运行期间的表示形式,通常包括:类的版本、字段、方法、接口等信息

    • 在方法区中分配
    • 通常在加载类和接口到JVM后,就创建相应的运行时常量池

    2. 栈、堆、方法区的交互关系

    2.1对象的访问定位

    在JVM规范中只规定了reference类型是一个指向对象的引用,但没有规定这个引用具体如何去定位、访问堆中对象的具体位置

    因此对象的访问方式取决于JVM的实现,目前主流的有:使用句柄或使用指针两种方式

    image.png
    HotSpot是使用指针的方式来访问对象

    Java堆中会存放访问类元数据的地址
    reference存储的就直接是对象的地址


    image.png

    3 Java堆的结构

    • 新生代用来放新分配的对象;新生代中经过垃圾回收,没有回收掉的对象,被复制到老年代
    • 老年代存储对象比新生代存储对象的年龄大得多
    • 老年代存储一些大对象
    • 整个堆大小 = 新生代 + 老年代
    • 新生代 = Eden + 存货区
    • 从前的持久代,用来存放Class、Method等元信息的区域,从JDK8开始去掉了,取而代之的是元空间(MetaSpace),元空间并不在虚拟机里面,而是直接使用本地缓存

    4 对象的内存布局

    • 对象在内存中存储的布局(这里以HotSpot虚拟机为例来说明),分为:对象头、实例数据和对齐填充

    • 对象头,包括两个部分:
      (1)Mark Word:存储对象自身的运行数据,如:HashCode、GC分代存储、锁状态标志等。
      (2)类型指针:对象指向它的类元数据的指针

    • 实例数据
      真正存放对象实例数据的地方

    • 对齐填充
      这部分不一定存在,也没有什么特别含义,仅仅是占位符。
      因为HotSpot要求对象起始地址都是8字节的整数倍,如果不是,就对齐,

    相关文章

      网友评论

        本文标题:深入JVM9 运行时数据区

        本文链接:https://www.haomeiwen.com/subject/naokzktx.html