JAVA编程【JVM编程】

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

相关推荐
m0_6138562932 分钟前
mysql如何利用事务隔离级别解决特定业务冲突_mysql隔离方案选型
jvm·数据库·python
abcnull1 小时前
用javaparser做精准测试
java·ast·静态代码分析·精准测试·javaparser
叶小鸡1 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
juniperhan1 小时前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054731 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
c++之路2 小时前
C++23概述
java·c++·c++23
专注API从业者3 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
摇滚侠3 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY3 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端