• 深入理解JVM(一)Java内存区域


    运行时数据区

    jvm数据区

    • 程序计数器

      当前线程执行的字节码的行号指示器

      每条线程都有独立的程序计数器,各线程之间计数器互不影响,独立存储。

      如果执行的是java方法,计数器记录正在执行的虚拟机字节码指令的位置;

      如果执行的是native方法,计数器值为空(undefined)

    • 虚拟机栈

      每个方法在执行的同时会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出入口等信息。

      一个方法从调用到执行完成就对应栈帧从入栈到出栈。

      两种异常:

      1. 线程请求栈深度大于虚拟机允许的最大深度,StackOverFlowError
      2. 如果虚拟机允许栈动态拓展,且在拓展时无法申请到足够内存,抛出OutOfMemoryError
    • 唯一目的,存放对象实例,也称为GC堆

      是GC管理的主要区域

    • 方法区

      存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据

      方法区是JVM的一种规范,落地可能是不同的实现

      PermGen space 是 JDK7及之前, HotSpot 虚拟机 对 方法区 的一个落地实现。在JDK8被移除。

      Metaspace(元空间)是 JDK8及之后, HotSpot 虚拟机 对 方法区 的新的实现。

      元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存

      当方法区无法满足内存分配要求,抛出OutOfMemoryError

    对象初始化过程

    对象初始化

    对象的内存布局

    对象在内存中存储的布局可以分为三块区域:对象头(Header),实例数据(Instance Data),对齐填充(Padding)

    • 对象头

      长度一般为32位或者64位,分为两部分信息:一部分用于存储对象自身的运行时数据,如哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程的ID,偏向时间戳等,称之为Mark Word。另一部分是类型指针,是对象指向他的类元数据的指针,用于确定是哪个类的实例(非必须);如果是数组还需要有一块记录数组长度的数据

    • 实例数据

      在程序代码中定义的各种类型的字段内容,无论是继承的还是自己的。

    • 对齐填充

      非必须,内存管理系统要求对象起始地址必须是8字节的整数倍,通常用于填充实例数据。

    对象的访问方式

    java程序通过栈上的reference数据来操作对象。常用的有两种,使用句柄直接指针

    • 使用句柄

      java堆中划出一块用于存储句柄(句柄池),reference存储的就是句柄地址

      img

      好处是当对象被移动时只需要修改句柄中实例数据地址

    • 使用指针

      reference存储对象地址,对象存在在堆中同时需要存储到对象类型的指针和对象实例数据

      好处是减少了一次指针定位的开销,Sun HotPot是以这种方式访问的

      img

  • 相关阅读:
    2017年总结
    计算机基础之进制转换详解
    随机总数字里面选取随机数字进行随机排序案例(JAVA实现)
    XML学习入门
    位运算从入门到入狱第一弹----原创!
    MYSQL数据库引擎区别详解
    时间戳
    数据库三大范式整理
    数组
    JS全选与不选、反选
  • 原文地址:https://www.cnblogs.com/CodingJacob/p/13099696.html
Copyright © 2020-2023  润新知