《深入理解jvm》笔记---第二章

第一章  Java内存区域与内存溢出异常

1.      JVM的运行时数据区划分:

JVM的运行时数据区

《深入理解jvm》笔记---第二章_第1张图片

Java虚拟机会在执行Java程序的过程中把内存划分为上图所示的若干数据区域,这些区域有各自的用途、创建时间和销毁时间。

①程序计数器:程序计数器是当前线程所执行的字节码的行号指示器。它是线程所私有的。

②Java虚拟机栈:方法在执行的时候会创建相应的方法栈,用来保存局部变量、操作数栈、动态链接、方法出口等信息。它也是线程所私有的。

③本地方法栈:与虚拟机栈类似,不过它是native方法的栈

④Java堆:Java堆是所有线程共享的一块区域,在虚拟机启动时创建,它的唯一目的就是保存对象实例。Java堆是垃圾收集器管理的主要区域,因此Java堆也叫作“GC堆”。

⑤方法区:方法区是各个线程共享的一块区域,它用于存储已被虚拟机加载的类信息即时编译器编译后的代码常量静态变量等数据。

  运行时常量池:运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用(“符号引用是什么,为什么需要符号引用”见第六章整理)。

2.      Java对象的创建过程:

①先检测这个指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用所代表的类是否已被加载、解析和初始化过,如果没有,要先执行类加载过程;

②类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可完全确定;

③内存分配完成后,虚拟机需要将分配到的内存空间全部初始化为零值(不包括对象头)。

④接下来虚拟机需要对对象进行必要的设置,例如这个对象是哪个类的实例、如何找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头(Object Head)中。

⑤执行<init>方法,把对象按照程序员的意愿进行初始化。

3.      Java对象的内存布局:

在HotSpot虚拟机中,对象的内存布局可以分为3个区域:对象头(Object Header)、实例数据(instance data)、对齐填充(padding)。

①对象头:包括两部分信息:

     I.存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳。

     II.存储类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针确定这个对象是哪个类的实例。如果对象是一个数组,那么在对象头中还有一个记录数组长度的数据。

         ②实例数据:对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中所定义的,都需要记录下来

         ③对齐填充:并不是必然存在的,也没有特别的含义,仅仅起到占位符的作用。因为对象的起始地址必须要地址对齐,像HotSpot中要求对象的起始地址必须是8字节的整数倍,也就是所有对象的大小要是8字节的整数倍,而对象头必然是8字节的整数倍,所以当实例数据部分没有对齐时需要填充来进行对齐。

4.      对象的访问定位:

Java程序通过站上的reference来操作堆上的具体的对象。主流的对象访问方式有句柄和直接指针两种:

通过句柄访问对象

《深入理解jvm》笔记---第二章_第2张图片

通过直接指针访问对象


你可能感兴趣的:(jvm)