JVM基础原理


JVM基础原理

jvm基础

jvm是什么?

jvm是运行在操作系统上的执行.class文件的虚拟机

jvm与操作系统的关系?

相同点都是可以执行对应的程序
不同点是jvm是可执行class文件与操作系统中间的一层(ps:某人说过计算机世界中的问题如果一个中间层不能解决就再加一个☺️)

jvm、jdk、jre之间的关系?

  • jdk>jre>jvm>操作系统

JjvW4I.png

java虚拟机规范与Java语言规范之间的关系?

java虚拟机规范是定义执行.class文件的虚拟机的规范;
java语言规范是定义java文件的规范

jvm中的内存划分

java比c等系列的语言引以为豪的就是引入来自动内存管理机制,不让使用者在关心内存的管理。

  • 内存划分

Jvwl01.png

  1. 堆区
  2. 栈区(本地方法栈、java虚拟机栈)
  3. 程序计数器
  4. 本地内存(元空间、直接内存)

堆区

堆是一个由线程之间共享的内存区域。基本类型的对象会中栈上进行分配,而普通类型的对象会栈堆上进行分配。由于栈是线程独立的,因此就不存在并发问题

栈区

  • 虚拟机栈

Java虚拟机栈是基于线程级别的,每个线程都拥有独立都虚拟机栈。虚拟机栈的作用是存储栈帧栈帧的作用是是保存每个线程当前运行方法的状态或值。

栈值中分为:

  • 局部变量表(用于存放方法参数和方法内定义的局部变量)
  • 操作数栈(存放方法运行期间的操作数或结果)
  • 动态连接(方法调用过程中的动态连接)
  • 方法返回地址

程序计数器

程序计数器是用来标记当前线程正在执行的程序运行到哪了一行。

元数据空间

元数据空间是JDK8中划分出来的,用于替代JDK7已经之前的Perm区(永久代)
元数据空间存储class信息常量池方法数据方法代码等等

小结

jvm中运行的参数是在上的信息,栈上保存的引用指向的是中的对象,类信息常量等信息则是放在元数据空间中。

对象创建的过程

  • 类加载检查
  • 分配内存空间
  • 设置对象的头部信息(对象的类型、hashcode、锁状态等)
  • 执行init方法(初始化)
  • 返回对象的引用

对象的有两种创建方式,一种是通过TLAB分配内存,另一种是通过CAS + 自旋锁分配内存。

TLAB (Thread Local Allocation Buffer) 的使用场景:

  • 适用场景:
    1. 小对象优先: TLAB 主要用于分配小对象。 这里的“小”是相对于整个堆空间而言的,具体大小由 JVM 的配置参数决定(例如,TLABSize)。通常,这个值设置为几 KB 到几十 KB。
    2. 线程频繁创建对象: TLAB 的优势在于避免了线程间的竞争,因此特别适合线程频繁创建对象的场景。例如,Web 服务器处理大量请求时,每个请求处理线程可能会创建很多临时对象。
    3. 内存分配速度敏感的应用: 由于 TLAB 分配不需要同步,速度非常快,因此对内存分配速度要求高的应用场景非常适用。

CAS + 自旋锁 的使用场景:

  • 适用场景:
    1. 大对象: 当对象的大小超过 TLAB 的限制时,必须直接在共享堆中分配内存。
    2. TLAB 分配失败: 当 TLAB 空间不足时,线程需要从共享堆中重新申请新的 TLAB 或直接分配对象。
    3. 高并发环境: 虽然 TLAB 减少了线程间的竞争,但在并发量非常高的场景下,仍然可能出现多个线程同时尝试在堆中分配内存的情况。
    4. 竞争不是特别激烈的场景: 自旋锁适用于竞争不是特别激烈的场景。如果竞争非常激烈,线程长时间自旋会消耗大量的 CPU 资源。

小结:

  • 优先使用 TLAB: JVM 会尽可能地使用 TLAB 来分配小对象,以提高分配速度和减少线程间的竞争。
  • TLAB 不足时使用 CAS + 自旋锁: 当 TLAB 空间不足或需要分配大对象时,JVM 会使用 CAS + 自旋锁 来在共享堆中分配内存。
  • 动态调整和优化: JVM 会根据具体的应用场景和硬件环境,动态调整 TLAB 的大小和自旋锁的策略,以达到最佳的性能和资源利用率。

更形象的比喻:

  • TLAB 就像每个线程的“私人储物柜”: 线程可以快速地将一些常用的物品(小对象)存放在自己的储物柜中,无需和其他线程竞争。
  • CAS + 自旋锁 就像“公共储物柜”: 如果物品太大或私人储物柜已满,线程需要到公共储物柜中寻找空间。如果公共储物柜正在被其他线程使用,则需要等待(自旋)直到可用。

类的加载机制

流程

加载 > 验证 > 准备 > 解析 > 初始化

执行时机早于,因为在装载到元数据区时就进行执行。

类加载器

  • Bootstrap ClassLoader

最底层的类加载器,用于加载java底层类的类加载器

  • Extention ClassLoader

扩展类的类加载器,用于加载lib/ext下的文件

  • App ClassLoader

应用加载器,用于加载classPath下的文件

  • Custom ClassLoader

自定义的类加载器


  TOC