1. JVM 体系结构
JVM 主要包括以下几个核心部分:
类加载器(ClassLoader)
运行时数据区(Runtime Data Area)
执行引擎(Execution Engine)
本地方法接口(Native Interface)
JVM 运行流程如下:
Java 源码 → 字节码(.class 文件)
类加载器 加载字节码到 JVM
字节码校验 确保字节码合法
解释器 & JIT 编译器 执行字节码
垃圾回收 释放无用对象
2. 类加载机制
类加载是指 JVM 将 .class 文件加载到内存,并将其转换为 Class 对象。
类加载过程
JVM 采用 双亲委派模型 进行类加载,过程如下:
加载(Loading):从磁盘或网络读取 .class 文件
验证(Verification):检查 .class 文件的格式与安全性
准备(Preparation):分配静态变量内存
解析(Resolution):将符号引用转换为直接引用
初始化(Initialization):执行静态代码块
代码示例
自定义一个类加载器:
            
            
              java
              
              
            
          
          import java.io.*;
public class MyClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] data = loadClassData(name);
        return defineClass(name, data, 0, data.length);
    }
    private byte[] loadClassData(String name) {
        try {
            File file = new File(name.replace(".", "/") + ".class");
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int b;
            while ((b = fis.read()) != -1) {
                baos.write(b);
            }
            fis.close();
            return baos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static void main(String[] args) throws Exception {
        MyClassLoader loader = new MyClassLoader();
        Class<?> clazz = loader.loadClass("com.example.MyClass");
        System.out.println("Class loaded: " + clazz.getName());
    }
}
        此代码实现了一个自定义类加载器,手动读取 .class 文件并加载。
3. 运行时数据区
JVM 运行时数据区包括:
方法区(Method Area)
堆(Heap)
虚拟机栈(JVM Stack)
本地方法栈(Native Method Stack)
程序计数器(PC Register)
内存分区示例
            
            
              java
              
              
            
          
          public class MemoryTest {
    static int staticVar; // 方法区
    int instanceVar;      // 堆
    void method() {
        int localVar = 10; // JVM 栈
    }
}
        staticVar 存在 方法区
instanceVar 存在 堆
localVar 存在 JVM 栈
4. JVM 执行引擎
JVM 主要有两种执行方式:
解释执行(Interpreter):逐行执行字节码,速度较慢
JIT(Just-In-Time 编译器):热点代码编译成机器码,提高性能
JIT 代码优化
JIT 会优化热点代码,例如:
            
            
              java
              
              
            
          
          public class JITTest {
    public static void main(String[] args) {
        long start = System.nanoTime();
        for (int i = 0; i < 1_000_000; i++) {
            Math.pow(i, 2); // 热点代码
        }
        long end = System.nanoTime();
        System.out.println("Execution Time: " + (end - start) / 1_000_000 + "ms");
    }
}
        JVM 会对 Math.pow(i, 2) 进行优化,提高执行效率。
5. 垃圾回收(GC)
垃圾回收用于回收无用对象,JVM 主要有以下几种垃圾回收器:
Serial GC(单线程)
Parallel GC(多线程)
CMS GC(低停顿)
G1 GC(大内存优化)
ZGC / Shenandoah GC(超低延迟)
对象生命周期
JVM 采用 GC Roots 可达性分析:
            
            
              java
              
              
            
          
          public class GCTest {
    private static GCTest instance;
    public static void main(String[] args) {
        instance = new GCTest();
        instance = null; // 失去引用,等待 GC
        System.gc();      // 手动触发 GC
    }
    @Override
    protected void finalize() throws Throwable {
        System.out.println("GC is running!");
    }
}
        运行时可能会看到 GC is running!,表示对象被回收。
6. 逃逸分析与栈上分配
JVM 可能会优化对象分配,使其在栈上分配,减少 GC 负担。
代码示例
            
            
              java
              
              
            
          
          public class EscapeAnalysis {
    static class MyObject {
        int value;
    }
    public static void main(String[] args) {
        long start = System.nanoTime();
        for (int i = 0; i < 1_000_000; i++) {
            MyObject obj = new MyObject(); // 可能分配到栈上
            obj.value = 42;
        }
        long end = System.nanoTime();
        System.out.println("Execution Time: " + (end - start) / 1_000_000 + "ms");
    }
}
        如果 JIT 认为对象未逃逸,可能会在栈上分配,而非堆上。
7. JVM 调优
JVM 提供多种参数进行调优,如:
-Xmx512m:最大堆大小 512MB
-Xms512m:初始堆大小 512MB
-XX:+UseG1GC:启用 G1 GC
-XX:MaxGCPauseMillis=200:最大 GC 停顿时间 200ms
JVM 监控工具
可以使用以下工具监控 JVM:
jps:列出 Java 进程
jstat:监控 GC
jmap:查看内存分配
jstack:线程栈分析
VisualVM:可视化监控 JVM