跳至主要內容

EkkoSonya's Blog

好好学习,天天向上

JVM 八股14 - IDEA 运行流程

IDEA 点击运行后的流程

.java 文件  --javac-->  .class 文件  --java-->  执行
(源代码)    (编译)      (字节码)      (运行)     (程序)

java 是用来运行 .class 文件的,所以在用 java 之前,需要先用 javac 编译。


codejavajvm八股大约 3 分钟
JVM 八股15 - javac 和 java 命令

编译与运行

.java 文件  --javac-->  .class 文件  --java-->  执行
(源代码)    (编译)      (字节码)      (运行)     (程序)
  • javac:编译器,将 .java 源文件编译成 .class 字节码
  • java:运行器,启动 JVM 加载并执行 .class 文件

codejavajvm八股大约 3 分钟
JVM 八股16 - 类加载器分析

jdk jre | jar

┌─────────────────────────────────────────┐
│              JDK                         │
│  ┌────────────────────────────────────┐ │
│  │              JRE                    │ │
│  │  ┌────────────────────────────────┐│ │
│  │  │            JVM                 ││ │
│  │  │  (Java Virtual Machine)        ││ │
│  │  │   - 加载 .class                ││ │
│  │  │   - 执行字节码                 ││ │
│  │  └────────────────────────────────┘│ │
│  │   + 核心类库 (rt.jar)              │ │
│  │   - java.lang.*                    │ │
│  │   - java.util.*                    │ │
│  └────────────────────────────────────┘ │
│   + 开发工具                             │
│   - javac (编译器)                      │
│   - java (运行器)                       │
│   - javadoc (文档生成)                  │
│   - jdb (调试器)                        │
│   - jmap, jstack (性能分析)             │
└─────────────────────────────────────────┘

codejavajvm八股大约 4 分钟
JVM 八股17 - JVM 调优

JVM 调优

性能检测工具

  • 系统层面 (可以监控系统整体的资源使用情况,比如说内存、CPU、IO 使用情况、网络使用情况)
    • top
    • iostat
    • netstat
    • vmstat
  • JDK 自带的命令行工具层面
    • jps
    • jstat
    • jinfo
    • jmap
    • jhat
    • jstack
    • jcmd
    • 可以查看 JVM 运行时信息、内存使用情况、堆栈信息等

codejavajvm八股大约 5 分钟
JVM 八股10 - 垃圾收集3 (垃圾收集器 + GC类型)

垃圾收集器

垃圾收集算法是理论基础,定义了如何识别和回收垃圾;垃圾收集器是算法的具体实现,一个收集器可以实现一种或多种算法

JVM 的垃圾收集器主要分为两大类:分代收集器和分区收集器

分代收集器的代表是 CMS

分区收集器的代表是 G1 和 ZGC

分代是按对象年龄划分(新生代/老年代),针对性回收;分区是把堆切成独立小区域(Region),可预测停顿时间。

现代收集器(如 G1)结合两者:逻辑上分代,物理上分区。


codejavajvm八股大约 12 分钟
JVM 八股11 - 垃圾收集4 (ZGC)

垃圾收集器

ZGC

ZGC 是 JDK 11 时引入的一款低延迟的垃圾收集器,最大特点是将垃圾收集的停顿时间控制在 10ms 以内,即使在 TB 级别的堆内存下也能保持较低的停顿时间。

ZGC 也采⽤了复制算法,只不过做了重⼤优化,ZGC 在标记、转移和重定位阶段⼏乎都是并发的,这是 ZGC 实现停顿时间⼩于 10ms 的关键所在

alt text

关键技术

指针染色


codejavajvm八股大约 4 分钟
JVM 八股12 - 类加载

类加载机制

JVM 的操作对象是 Class 文件。JVM 把 Class 文件中描述类的数据结构加载到内存中,并对数据进行校验、解析和初始化,最终转化成可以被 JVM 直接使用的类型,这个过程被称为类加载机制。

类加载是运行时进行的,JVM 不会在启动时加载所有类,而是按需加载

触发类加载的时机(主动引用):

  • new 一个对象
  • 访问类的静态变量或静态方法
  • 使用反射(如 Class.forName()
  • 初始化子类时(会先触发父类加载)

不触发类加载的情况(被动引用):

  • 通过子类引用父类的静态变量
  • 定义类数组(如 MyClass[] arr
  • 常量引用(如 MyClass.CONST

codejavajvm八股大约 8 分钟
JVM 八股13 - 类加载分析

怎么使用自定义 ClassLoader

类加载器是在运行时动态决定的,不是编译时指定的。

当你写 new MyClass() 时,JVM 会使用定义当前类的同一个 ClassLoader去加载 MyClass

所以如果你想让某个类用自定义 ClassLoader 加载,有两种方式:

1. 直接使用自定义 ClassLoader(反射方式)

// 创建自定义类加载器
MyClassLoader classLoader = new MyClassLoader();

// 用它加载类(返回 Class<?>,不能用强类型)
Class<?> clazz = classLoader.loadClass("com.example.MyClass");

// 用反射创建实例
Object obj = clazz.newInstance();

codejavajvm八股大约 4 分钟
hint - 屏障

屏障

屏障 = 在某个操作前后插入的"检查点"或"钩子"

想象一个小区门禁:

居民进出 → [门禁屏障] → 记录谁进出了 → 放行

屏障不做"拦截",只做"记录"或"检查"

计算机中的屏障

内存屏障

CPU 为了性能会重排序指令,内存屏障告诉 CPU:

指令1
指令2
[内存屏障] ←  barrier 之前的指令必须先执行完
指令3
指令4

codejava hint大约 1 分钟
JVM 八股5 - 内存管理4 (对象内存布局)

对象内存布局

对象的内存布局是由 Java 虚拟机规范定义的,但具体的实现细节各有不同,如 HotSpot 和 OpenJ9 就不一样

常用的 HotSpot 为例:

对象在内存中包括三部分:对象头、实例数据和对齐填充

对象头 (Mark World + 类型指针 (指向 Class 对象)) + 实例数据 + 对齐填充

对象头 (8字节 + 8字节 (压缩 4 字节)): 12字节 (指针压缩)

对齐填充必须是 8 的倍数 (64位)

alt text

codejavajvm八股大约 5 分钟