深入理解 Java 虚拟机读书笔记1

Java 内存管理

Java 虚拟机对内存的划分主要包括:

  • 程序计数器
    线程私有,用于指示当前线程执行的字节码行号,保证线程切换后能恢复到正确的位置继续执行。此内存区域是唯一一个在 Java 虚拟机规范中没有规定任何 OOM 情况的区域。

  • Java 虚拟机栈
    线程私有,其生命周期和线程相同,描述的是 Java 方法执行的内存模型。每个方法从调用到完成,对应着一个栈帧(栈帧在方法执行时创建,用于存储局部变量表,操作数栈等)在虚拟机栈中入栈和出栈的过程。这部分会抛出两种异常(StackOverflowError,OOM)

    局部变量表
    存放着编译器可知的基本数据类型,对象引用(可能仅仅只是引用),returnAddress 类型。

  • Native 方法栈
    线程私有,想对于 Java 虚拟机栈,区别仅仅是执行的方法不同,这里执行的是 Native 方法。也会存在( StackOverflowError,OOM)

  • Java 堆
    线程共享,唯一目的就是用来存放对象实例。这块区域也是垃圾回收器重点工作区域。这里会存在 OOM 异常。

  • 方法区
    线程共享,存储已被虚拟机加载的静态变量,常量,类信息等,运行时常量池也是该区域的一部分(存放类加载后的常量池)。这里会存在 OOM 异常。

对象的创建

对象的创建
一个对象通过虚拟机创建通常会经过:

  • 类加载过程

  • 为新生对象分配内存

  • 为内存空间进行初始化

  • 对对象进行必要的设置

完成上述步骤后,在虚拟机的角度看,对象已经生成,而从应用程序的角度看对象才刚开始创建(因为初始化还没开始),只有紧接着完成初始化操作,对象才算真正的产生并可以使用。

对象的组成
对象在内存中的组成可分为:

  • 对象头

  • 实例数据

  • 对齐填充

对我们而言,需要关心的就是 实例数据 部分,包含了代码中定义的各种变量。

对象的访问
还记得在 Java 虚拟机栈中的局部变量表 中存储的对象引用吗?应用程序就是通过那部分的数据来操作 Java 堆上的具体对象。具体访问对象的方式有:

句柄访问与直接指针.jpg

  • 句柄访问
    优点是对象引用始终存储的是句柄地址,不随垃圾回收器清理 Java 堆时,对象被移动而改变。

  • 直接指针
    优点是速度更快。

你可能感兴趣的:(深入理解 Java 虚拟机读书笔记1)