爆肝整理JVM十大模块知识点总结,不信你还不懂

01 JVM 内存结构

Java 虚拟机的内存空间分为 5 个部分:

  • 程序计数器
  • Java 虚拟机栈
  • 本地方法栈
  • 方法区

爆肝整理JVM十大模块知识点总结,不信你还不懂_第1张图片

JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区取代了永久代。元空间的本质和永久 代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在虚拟机中,而是使用本地内存。

1.1 程序计数器(PC 寄存器)

(1)程序计数器的定义 程序计数器是一块较小的内存空间,是当前线程正在执行的那条字节码指令的地 址。若当前线程正在执行的是一个本地方法,那么此时程序计数器为 Undefined。

(2)程序计数器的作用

  • 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制。
  • 在多线程情况下,程序计数器记录的是当前线程执行的位置,从而当线程切换回 来时,就知道上次线程执行到哪了。

(3)程序计数器的特点  是一块较小的内存空间。

  • 线程私有,每条线程都有自己的程序计数器。
  • 生命周期:随着线程的创建而创建,随着线程的结束而销毁。
  • 是唯一一个不会出现 OutOfMemoryError 的内存区域。
由于文章篇幅问题,部门内容将以图片展示,如有小伙伴需完整文档进行查阅观看点赞+关注之后【点击此处】即可获取!!

1.2 Java 虚拟机栈(Java 栈)

(1)Java 虚拟机栈的定义 Java 虚拟机栈是描述 Java 方法运行过程的内存模型。

Java 虚拟机栈会为每一个即将运行的 Java 方法创建一块叫做“栈帧”的区域, 用于存放该方法运行过程中的一些信息,如:

  • 局部变量表
  • 操作数栈
  • 动态链接
  • 方法出口信息
  • ......

爆肝整理JVM十大模块知识点总结,不信你还不懂_第2张图片

(2)压栈出栈过程 当方法运行过程中需要创建局部变量时,就将局部变量的值存入栈帧中的局部变 量表中。

Java 虚拟机栈的栈顶的栈帧是当前正在执行的活动栈,也就是当前正在执行的 方法,PC 寄存器也会指向这个地址。只有这个活动的栈帧的本地变量可以被操 作数栈使用,当在这个栈帧中调用另一个方法,与之对应的栈帧又会被创建,新 创建的栈帧压入栈顶,变为当前的活动栈帧。

方法结束后,当前栈帧被移出,栈帧的返回值变成新的活动栈帧中操作数栈的一 个操作数。如果没有返回值,那么新的活动栈帧中操作数栈的操作数没有变化。

由于 Java 虚拟机栈是与线程对应的,数据不是线程共享的,因此不用关心数据 一致性问题,也不会存在同步锁的问题。

(3)Java 虚拟机栈的特点

  • 局部变量表随着栈帧的创建而创建,它的大小在编译时确定,创建时只需分配事 先规定的大小即可。在方法运行过程中,局部变量表的大小不会发生改变。
  • Java 虚拟机栈会出现两种异常:StackOverFlowError 和 OutOfMemoryError。
  • StackOverFlowError 若 Java 虚拟机栈的大小不允许动态扩展,那么当线程请 求栈的深度超过当前 Java 虚拟机栈的最大深度时,抛出 StackOverFlowError 异常。

爆肝整理JVM十大模块知识点总结,不信你还不懂_第3张图片

02 HotSpot 虚拟机对象探秘

2.1 对象的内存布局 在 HotSpot 虚拟机中,对象的内存布局分为以下 3 块区域:

  • 对象头(Header)
  • 实例数据(Instance Data)
  • 对齐填充(Padding)

爆肝整理JVM十大模块知识点总结,不信你还不懂_第4张图片

(1)对象头

对象头记录了对象在运行过程中所需要使用的一些数据:

  • 哈希码
  • GC 分代年龄
  • 锁状态标志
  • 线程持有的锁
  • 偏向线程 ID
  • 偏向时间戳

对象头可能包含类型指针,通过该指针能确定对象属于哪个类。如果对象是一个 数组,那么对象头还会包括数组长度。

(2)实例数据

实例数据部分就是成员变量的值,其中包括父类成员变量和本类成员变量。

(3)对齐填充

用于确保对象的总长度为 8 字节的整数倍。 HotSpot VM 的自动内存管理系统要求对象的大小必须是 8 字节的整数倍。而 对象头部分正好是 8 字节的倍数(1 倍或 2 倍),因此,当对象实例数据部 分没有对齐时,就需要通过对齐填充来补全。 对齐填充并不是必然存在,也没有特别的含义,它仅仅起着占位符的作用

爆肝整理JVM十大模块知识点总结,不信你还不懂_第5张图片

03 垃圾收集策略与算法

程序计数器、虚拟机栈、本地方法栈随线程而生,也随线程而灭;栈帧随着方法 的开始而入栈,随着方法的结束而出栈。这几个区域的内存分配和回收都具有确 定性,在这几个区域内不需要过多考虑回收的问题,因为方法结束或者线程结束 时,内存自然就跟随着回收了。而对于 Java 堆和方法区,我们只有在程序运行期间才能知道会创建哪些对象, 这部分内存的分配和回收都是动态的,垃圾收集器所关注的正是这部分内存。

3.1 判定对象是否存活

若一个对象不被任何对象或变量引用,那么它就是无效对象,需要被回收。

(1)引用计数法

在对象头维护着一个 counter 计数器,对象被引用一次则计数器 +1;若引用 失效则计数器 -1。当计数器为 0 时,就认为该对象无效了。

引用计数算法的实现简单,判定效率也很高,在大部分情况下它都是一个不错的 算法。但是主流的 Java 虚拟机里没有选用引用计数算法来管理内存,主要是因 为它很难解决对象之间循环引用的问题。

举个栗子对象 objA 和 objB 都有字段 instance,令 objA.instance = objB 并且 objB.instance = objA,由于它们互相引用着对方,导致它们的引用计数 都不为 0,于是引用计数算法无法通知 GC 收集器回收它们。

(2)可达性分析法

所有和 GC Roots 直接或间接关联的对象都是有效对象,和 GC Roots 没有关 联的对象就是无效对象。

GC Roots 是指:

  • Java 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈中引用的对象
  • 方法区中常量引用的对象
  • 方法区中类静态属性引用的对象

GC Roots 并不包括堆中对象所引用的对象,这样就不会有循环引用的问题。

爆肝整理JVM十大模块知识点总结,不信你还不懂_第6张图片

04 HotSpot 垃圾收集器

HotSpot 虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,虽然我 们要对各个收集器进行比较,但并非为了挑选出一个最好的收集器。我们选择的 只是对具体应用最合适的收集器。

4.1 新生代垃圾收集器

(1)Serial 垃圾收集器(单线程) 只开启一条 GC 线程进行垃圾回收,并且在垃圾收集过程中停止一切用户线程 (Stop The World)。

一般客户端应用所需内存较小,不会创建太多对象,而且堆内存不大,因此垃圾 收集器回收时间短,即使在这段时间停止一切用户线程,也不会感觉明显卡顿。 因此 Serial 垃圾收集器适合客户端使用。

由于 Serial 收集器只使用一条 GC 线程,避免了线程切换的开销,从而简单高 效。

爆肝整理JVM十大模块知识点总结,不信你还不懂_第7张图片

(2)ParNew 垃圾收集器(多线程)

ParNew 是 Serial 的多线程版本。由多条 GC 线程并行地进行垃圾清理。但 清理过程依然需要 Stop The World。

ParNew 追求“低停顿时间”,与 Serial 唯一区别就是使用了多线程进行垃圾收 集,在多 CPU 环境下性能比 Serial 会有一定程度的提升;但线程切换需要额 外的开销,因此在单 CPU 环境中表现不如 Serial。

爆肝整理JVM十大模块知识点总结,不信你还不懂_第8张图片

爆肝整理JVM十大模块知识点总结,不信你还不懂_第9张图片

05 内存分配与回收策略

爆肝整理JVM十大模块知识点总结,不信你还不懂_第10张图片

06 JVM 性能调优

在高性能硬件上部署程序,目前主要有两种方式:

  • 通过 64 位 JDK 来使用大内存;
  • 使用若干个 32 位虚拟机建立逻辑集群来利用硬件资源。

爆肝整理JVM十大模块知识点总结,不信你还不懂_第11张图片

07 类文件结构

爆肝整理JVM十大模块知识点总结,不信你还不懂_第12张图片

08 类加载的时机

爆肝整理JVM十大模块知识点总结,不信你还不懂_第13张图片

09 类加载的过程

爆肝整理JVM十大模块知识点总结,不信你还不懂_第14张图片

10 类加载器

10.1 类与类加载器

(1)判断类是否“相等” 任意一个类,都由加载它的类加载器和这个类本身一同确立其在 Java 虚拟机中 的唯一性,每一个类加载器,都有一个独立的类名称空间。

因此,比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前 提下才有意义,否则,即使这两个类来源于同一个 Class 文件,被同一个虚拟 机加载,只要加载它们的类加载器不同,那么这两个类就必定不相等。 这里的“相等”,包括代表类的 Class 对象的 equals() 方法、isInstance() 方 法的返回结果,也包括使用 instanceof 关键字做对象所属关系判定等情况。

爆肝整理JVM十大模块知识点总结,不信你还不懂_第15张图片

你可能感兴趣的:(jvmjava程序员)