JVM 入门学习笔记(内存模型 / GC / 类加载机制)

整理一下基本概念,因为遇到了本地线程无法创建的问题,回顾一下基本JVM的,有利于解决所需要的理论知识


一、JVM 内存模型

1. 什么是 JVM

JVM(Java Virtual Machine)本质上是:

text 复制代码
Java代码的运行环境

Java代码不会直接运行在操作系统上。

而是:

text 复制代码
Java代码
   ↓
编译成.class字节码
   ↓
JVM解释执行

所以 JVM 本质上是:

text 复制代码
Java程序和操作系统之间的一层中间层

二、堆和栈到底是什么

这是 JVM 最核心概念。


1. 栈(Stack)

栈是:

text 复制代码
线程私有的运行空间

每个线程:

text 复制代码
都有自己的栈

例如:

  • main线程
  • Tomcat工作线程
  • GC线程

都有自己的栈。


2. 栈里存什么

栈主要存:

  • 方法调用
  • 局部变量
  • 基本类型
  • 对象引用地址

例如:

java 复制代码
User user = new User();
int age = 18;

运行时:

text 复制代码
栈:
user = 对象地址
age = 18

3. 堆(Heap)

堆是:

text 复制代码
所有线程共享的对象存储区

真正对象:

text 复制代码
放在堆里

例如:

java 复制代码
new User()

会进入:

text 复制代码
Heap(堆)

4. 栈和堆的关系

text 复制代码
栈(Stack)                  堆(Heap)

user  ───────────────→   User对象
                           name
                           age
                           phone

核心:

text 复制代码
栈保存地址
堆保存真正对象

三、为什么对象不直接放栈里

因为:

text 复制代码
对象可能很大
生命周期不确定

例如:

  • List
  • Map
  • JSON
  • Redis缓存对象
  • Spring Bean

如果都放栈里:

text 复制代码
线程内存会瞬间爆炸

所以 JVM 设计成:

区域 作用
快速执行方法
管理大量对象

四、线程、HTTP请求、栈之间关系

很多人误会:

text 复制代码
HTTP请求来了才创建栈

其实不是。

真正是:

text 复制代码
线程创建时
栈就已经存在

核心:

text 复制代码
一个线程 = 一个虚拟机栈

SpringBoot 启动时

JVM 会创建很多线程:

  • main线程
  • GC线程
  • Tomcat线程
  • 定时任务线程

每个线程:

text 复制代码
都有自己的栈

五、虚拟机栈 vs 本地方法栈


1. Java虚拟机栈

负责:

text 复制代码
Java方法运行

例如:

  • Controller
  • Service
  • DAO

2. 本地方法栈

负责:

text 复制代码
Native方法运行

例如:

  • 文件IO
  • 网络IO
  • 操作系统调用
  • 创建线程

很多 JVM 底层能力:

text 复制代码
实际上是C/C++实现

六、GC(垃圾回收)到底是什么

GC:

text 复制代码
Garbage Collection

即:

text 复制代码
垃圾回收

负责:

text 复制代码
回收堆中的无用对象

七、OOM(内存溢出)是什么

最经典:

text 复制代码
java.lang.OutOfMemoryError: Java heap space

表示:

text 复制代码
堆满了

OOM 本质

不是简单:

text 复制代码
GC太慢

真正本质:

text 复制代码
对象创建速度
>
对象释放速度

或者:

text 复制代码
对象一直被引用
无法回收

八、GC Roots 与可达性分析

这是 JVM GC 核心。

GC 并不会判断:

text 复制代码
对象有没有业务价值

而是判断:

text 复制代码
还能不能找到对象

1. 什么是 GC Roots

GC Roots:

text 复制代码
GC扫描的起点

常见 GC Roots:

类型 示例
栈引用 方法里的变量
static变量 静态缓存
正在运行线程 Thread
常量引用 String常量池

2. GC 扫描逻辑

text 复制代码
GC Roots
   │
   ├──── 能找到对象
   │         │
   │         └──── 对象存活
   │
   └──── 找不到对象
             │
             └──── 对象死亡

3. 为什么 static 容易OOM

例如:

java 复制代码
static Map cache = new HashMap();

因为:

text 复制代码
static属于GC Roots

所以:

text 复制代码
cache中的对象长期可达
GC不敢删

4. 为什么 ThreadLocal 容易泄漏

因为:

text 复制代码
线程本身是GC Roots

Tomcat线程池长期存在。

所以:

text 复制代码
ThreadLocalMap中的对象
长期无法回收

九、分代垃圾回收机制

JVM发现:

text 复制代码
大部分对象生命周期很短

所以:

text 复制代码
把不同生命周期对象分开管理

1. 堆结构

text 复制代码
堆
├── 新生代
└── 老年代

十、新生代

新对象:

text 复制代码
先进入新生代

结构:

text 复制代码
新生代
├── Eden
├── Survivor From
└── Survivor To

对象流转

text 复制代码
new对象
   │
   ▼
Eden
   │
   ▼
Minor GC
   │
   ├── 死亡 → 回收
   └── 存活 → Survivor
                    │
                    ▼
              多次存活
                    │
                    ▼
                 老年代

十一、Minor GC 和 Full GC


1. Minor GC

触发时机:

text 复制代码
Eden区满了

特点:

  • 频繁
  • 回收年轻对象

2. Full GC

触发时机:

text 复制代码
老年代空间不足

特点:

  • 很慢
  • Stop The World
  • 扫描整个堆

十二、GC 什么时候执行

GC 并不是:

text 复制代码
方法结束立即执行

而是:

text 复制代码
内存不够时触发

正确流程

text 复制代码
方法结束
   │
   ▼
对象失去引用
   │
   ▼
变成"可回收对象"
   │
   ▼
等待GC触发
   │
   ▼
GC扫描
   │
   ▼
真正回收

十三、类加载机制

Java类不会自动进入JVM。

必须:

text 复制代码
ClassLoader加载

JVM默认三层类加载器

text 复制代码
Application ClassLoader
            ↑
Extension ClassLoader
            ↑
Bootstrap ClassLoader

各自职责

类加载器 负责内容
Bootstrap JDK核心类
Extension 扩展类库
Application 业务代码

十四、双亲委派机制

核心思想:

text 复制代码
加载类时
先问父加载器
父加载不了
自己再加载

加载流程

text 复制代码
Application收到请求
   │
   ▼
先问Extension
   │
   ▼
Extension问Bootstrap
   │
   ▼
Bootstrap能加载?
   │
 ┌─┴───────┐
 │          │
能         不能
 │          │
Bootstrap   返回下层
加载         │
             ▼
       最终Application加载

十五、双亲委派为什么重要

1. 防止核心类被篡改

例如:

java 复制代码
java.lang.String

只能由:

text 复制代码
Bootstrap加载

业务代码无法替换。


2. 防止类重复加载

JVM 中:

text 复制代码
类名 + ClassLoader
=
唯一类

3. 保证安全隔离

Tomcat 能同时运行多个项目:

text 复制代码
因为每个项目有自己的ClassLoader

十六、今天最核心的理解


JVM 内存

text 复制代码
栈:线程私有
堆:对象存储

GC

text 复制代码
GC判断对象是否死亡
看的是:
还能不能从GC Roots找到

分代GC

text 复制代码
不同生命周期对象
采用不同回收策略

双亲委派

text 复制代码
本质是:
优先级 + 安全机制

防止:

  • 核心类被覆盖
  • 类重复加载
  • 恶意注入


十八、现实世界类比总结(帮助真正理解)


1. JVM 像什么?

JVM 可以理解成:

text 复制代码
Java程序的"操作系统"

它负责:

  • 管理内存
  • 管理线程
  • 管理对象
  • 管理类加载
  • 管理垃圾回收

就像:

text 复制代码
一个大型公司的总管理系统

2. 栈(Stack)像什么?

栈像:

text 复制代码
每个员工自己的办公桌

特点:

  • 私有
  • 快速
  • 临时
  • 方法结束立刻清理

所以:

text 复制代码
一个线程 = 一张办公桌

3. 堆(Heap)像什么?

堆像:

text 复制代码
公司公共仓库

所有线程:

text 复制代码
共享这个仓库

真正的大对象:

  • List
  • Map
  • Bean
  • DTO
  • JSON

都放在这里。


4. 对象引用像什么?

代码:

java 复制代码
User user = new User();

本质像:

text 复制代码
办公桌上放着"仓库货架编号"

即:

text 复制代码
栈里放地址
堆里放真正对象

5. GC 像什么?

GC 像:

text 复制代码
公司保洁 + 仓库管理员

负责:

text 复制代码
清理没人使用的物品

6. GC Roots 像什么?

GC Roots 像:

text 复制代码
公司总台登记系统

GC 会从"总台记录"开始查:

text 复制代码
这个东西还有没有人能找到

如果:

text 复制代码
还能找到

说明:

text 复制代码
对象还活着

否则:

text 复制代码
对象死亡

7. Minor GC 像什么?

Minor GC 像:

text 复制代码
快递临时区清理

因为:

text 复制代码
大部分快递当天就会拿走

所以:

text 复制代码
清理特别快

8. 老年代像什么?

老年代像:

text 复制代码
公司长期仓库

放:

  • 核心设备
  • 长期资产
  • 大型机器

特点:

text 复制代码
东西多
清理慢

9. Full GC 像什么?

Full GC 像:

text 复制代码
整个公司停工大扫除

所以:

text 复制代码
会暂停业务

即:

text 复制代码
Stop The World

10. 双亲委派像什么?

双亲委派像:

text 复制代码
公司逐级审批制度

基层:

text 复制代码
不能直接覆盖总部规定

必须:

text 复制代码
先问上级

这就是:

text 复制代码
先委派父加载器

11. Bootstrap ClassLoader 像什么?

Bootstrap 类加载器像:

text 复制代码
公司董事长 / 国家中央系统

负责:

text 复制代码
最核心最重要的类

例如:

  • String
  • Object
  • Thread
  • Class

这些:

text 复制代码
绝对不能被业务代码替换

12. ThreadLocal 为什么容易泄漏?

ThreadLocal 像:

text 复制代码
员工工位抽屉

如果:

text 复制代码
员工一直不离职

抽屉里的东西:

text 复制代码
永远不会被清理

Tomcat线程池就是这样。


13. OOM 像什么?

OOM 像:

text 复制代码
仓库塞满了

可能因为:

  • 东西产生太快
  • 垃圾清理太慢
  • 有人一直占着不丢

最终:

text 复制代码
仓库彻底放不下

十九、最终一句总结

JVM 最核心其实只有一句话:

text 复制代码
对象如何创建
对象如何存活
对象如何死亡

而:

  • 内存模型
  • GC
  • 类加载

本质上都是围绕:

text 复制代码
对象生命周期管理

展开的。

相关推荐
克里斯蒂亚诺更新3 小时前
ruoyi角色权限的对应关系
笔记
a1117766 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao6 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
破碎的南瓜7 小时前
sqli--sql注入过关笔记(1,2,3,4,5,9)
数据库·笔记·sql
你想知道什么?8 小时前
线性回归-学习笔记
笔记·学习·线性回归
鱼毓屿御8 小时前
从「只会聊」到「边想边做」的跃迁
前端·学习·react.js
谙弆悕博士8 小时前
系统集成项目管理工程师教程(第3版)笔记——第17章:法律法规和标准规范
笔记·职场和发展·学习方法·业界资讯·软考·法律·法规
AOwhisky9 小时前
Python 学习笔记(第十五期)——运维自动化(下·后篇):堡垒机实战——paramiko高阶篇
运维·python·学习·云原生·自动化·运维开发
谙弆悕博士10 小时前
系统集成项目管理工程师教程(第3版)笔记——第4章:信息系统架构
笔记·系统架构·项目管理·创业创新·学习方法·业界资讯·物理
minglie111 小时前
zynq中linux系统的自动登录和免密登录
学习