当前位置: 首页 > news >正文

01-JVM 内存模型与 GC 原理

JVM 内存模型与 GC 原理解析

本文将从 JVM 内存模型入手,深入剖析各个区域的作用、GC 的运行机制与常见算法,并结合源码与面试思维,带你掌握 JVM 的底层世界。


一、JVM 内存模型(Java Memory Model)

JVM 将内存划分为若干区域,每个区域有其独立职责:

  • 程序计数器(线程私有)
  • 虚拟机栈(线程私有)
  • 本地方法栈
  • 堆(Heap)
  • 方法区(MetaSpace)

在这里插入图片描述


二、重点区域解析

2.1 堆(Heap)

  • 所有对象实例、数组存放在堆中。
  • -Xms-Xmx 设置堆初始与最大值。
  • GC 的核心目标区域。
public class HeapOOM {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        while (true) {
            list.add(new byte[1024 * 1024]);
        }
    }
}

💡 备注:
Q:什么情况下会抛出 OutOfMemoryError?
A:当申请内存超出堆最大容量时,GC 无法回收足够空间就会 OOM。

三、GC(垃圾回收)机制解析

GC 并非作用于所有内存区域,而是只关注堆和方法区。

3.1 常见垃圾回收算法

  • 标记-清除

  • 复制算法

  • 标记-整理

  • 分代回收

3.2 分代回收机制

JVM 将堆划分为:

  • 新生代(Young Generation)

  • 老年代(Old Generation)

具体如:

Young Gen:
  Eden + SurvivorFrom + SurvivorTo
Old Gen:
  Tenured

四、主流 GC 垃圾收集器

收集器作用代算法适用场景
Serial新生代复制单线程小应用
ParNew新生代复制多线程环境
CMS老年代标记清除响应快
G1整堆分区整理低延迟大内存
ZGC整堆并发标记复制超大内存场景
# 示例:开启 G1 收集器
-XX:+UseG1GC

五、GC 日志分析与调优

-XX:+PrintGCDetails -Xloggc:gc.log

典型日志解读:

[GC (Allocation Failure) [PSYoungGen: 512K->128K(768K)] 1024K->512K(1536K)]

含义:

  • Young GC 发生

  • Eden 区释放

  • 堆总容量变化

六、源码视角下的 GC 行为

G1为例:

// G1GC 内部空间定义
class G1CollectedHeap : public CollectedHeap {
    ...
    HeapRegion* _regions;
}

G1Policy::record_collection_pause_end() 中控制回收行为:

void G1Policy::record_collection_pause_end(...) {
    update_young_list_target_length();
    update_old_gen_estimates();
}

七、JVM 常见调优策略

  • 设置合适堆大小,避免频繁 Full GC:
-Xms2g -Xmx2g
  • 优化 GC 策略(G1 替代 CMS):
-XX:+UseG1GC
  • 利用 JVM 工具链(如 jmap、jstat、VisualVM)

📌 面试问答分析(Q&A)

💬 Q1:GC 会回收哪些区域?
✅ A1:只会回收堆和方法区(Java 8 开始为元空间 MetaSpace)。

💬 Q2:Minor GC 和 Full GC 有什么区别?
✅ A2:Minor 仅作用于新生代,速度快;Full 会触发老年代,速度慢。

💬 Q3:如何定位 OOM 的位置?
✅ A3:结合 -XX:+HeapDumpOnOutOfMemoryError 输出内存快照,用 MAT 工具分析。

✅ 总结

本文从 JVM 的内存模型出发,详细解析了堆结构、GC 算法与主流收集器,结合日志调优与源码进行系统讲解,并融入了面试视角与实战经验。掌握 JVM 原理是 Java 工程师高阶进阶的必经之路。

📌 后续预告:下一篇将深入分析 Java 类加载机制及其破坏与替代方案,敬请期待。

相关文章:

  • 蓝桥杯-蓝桥幼儿园(并查集)
  • 采用小程序远程控制LED灯亮灭
  • 数据库中的数组: MySQL与StarRocks的数组操作解析
  • Pytorch的安装和使用
  • 深入解析 Jenkins Agent 的 .jnlp 启动文件
  • MuJoCo 仿真 + TOPPRA 最优时间轨迹规划!机械臂运动效率拉满(附代码)
  • 小刚说C语言刷题——第18讲 循环之while和do-while语句
  • 深入理解Spring IoCDI
  • Pandas 库
  • Streamlit性能优化:缓存与状态管理实战
  • Elasticsearch:加快 HNSW 图的合并速度
  • 自己搭建cesium应用程序
  • 河道违建检测数据集VOC+YOLO格式223张1类别
  • spdlog C++日志库使用教程
  • 试剂SYBR 14核酸染料在染色时的操作步骤(说明)
  • 【python3】关于像素密度计算
  • AI大模型从0到1记录学习 day15
  • 初识 Three.js:开启你的 Web 3D 世界 ✨
  • 【android bluetooth 框架分析 01】【关键线程 2】【bt_stack_manager_thread线程介绍】
  • 告别运动控制不同步:某车企用异构PLC实现99.98%焊接合格率
  • 央行设立服务消费与养老再贷款,额度5000亿元
  • 纪录片《中国》原班人马打造,《船山先生》美学再升级
  • 美联储主席:关税“远超预期”,美联储实现目标的进程或被推迟至明年
  • 紧盯大V、网红带货肉制品,整治制售假劣肉制品专项行动开展
  • 印巴冲突升级,巴防长称已击落5架印度战机
  • 上海飞银川客机触地复飞后备降西安,亲历者:不少乘客都吐了