学习笔记02——《深入理解Java虚拟机(第三版)》第三章

embedded/2025/2/24 22:01:57/

一、核心脉络:垃圾回收与内存分配策略

核心命题:JVM如何高效管理内存的分配与回收? 三大核心机制

  1. 对象存活判定(引用追踪 vs 可达性分析)

  2. 垃圾回收算法(标记-清除/复制/标记-整理/分代)

  3. 垃圾收集器实现(Serial/Parallel/CMS/G1等)


二、深度解析核心知识点

1. 对象存活判定

(1) 引用计数法(非JVM方案)
  • 原理:对象被引用时计数器+1,引用失效时-1,归零即回收

  • 致命缺陷:无法解决循环引用问题(A→B→A)

(2) 可达性分析算法(JVM实际方案)
  • GC Roots对象类型

    • 虚拟机栈局部变量表引用的对象

    • 方法区中类静态属性引用的对象

    • 方法区中常量引用的对象

    • 本地方法栈JNI引用的Native对象

    • 同步锁持有的对象(synchronized)

    • 内部引用(Class对象、异常对象、类加载器等)

  • 二次标记机制: 第一次标记后进入“缓刑”阶段,若未重写finalize()或已被调用过,则直接回收

2. 四大经典垃圾回收算法

算法核心思想优势缺陷
标记-清除标记存活对象,清除未标记区域实现简单内存碎片化,大对象分配困难
复制算法将内存分为两块,每次使用一块,存活对象复制到另一块无碎片,高效内存利用率仅50%
标记-整理标记存活对象后向一端移动,清理边界外内存无碎片,适合老年代移动对象开销大
分代收集基于对象的生命周期,将堆内存划为新生代和老年代;分别采用不同的回收方法。新生代(复制算法)、老年代(标记-清除/整理)针对性优化,平衡效率与空间需要处理跨代引用问题

3. 主流垃圾收集器对比(重点!)

收集器工作区域线程模式算法特点
Serial新生代单线程复制简单高效,Client模式默认,STW时间敏感场景慎用
ParNew新生代多线程复制Serial的多线程版本,需配合CMS使用
Parallel Scavenge新生代多线程复制吞吐量优先,适合后台计算型应用
CMS老年代并发标记-清除低延迟,四阶段流程(初始标记→并发标记→重新标记→并发清除),内存碎片问题显著
G1全堆并发+并行分区+标记-整理可预测停顿时间,将堆划分为Region,兼顾吞吐与延迟,JDK9默认
ZGC全堆并发染色指针+读屏障亚毫秒级停顿,TB级堆支持,JDK11引入

4. 内存分配策略

  • 对象优先在Eden分配:多数对象朝生夕死,Eden区采用复制算法

  • 大对象直接进老年代:避免在新生代反复复制(-XX:PretenureSizeThreshold参数控制)

  • 长期存活对象晋升:对象年龄计数器(-XX:MaxTenuringThreshold)

  • 空间分配担保:Minor GC前检查老年代剩余空间是否大于历次晋升对象平均大小

5.垃圾收集器的性能调优

(一)选择合适的垃圾收集器

根据应用的特点选择合适的垃圾收集器: • 低延迟需求:CMS或G1。 • 高吞吐量需求:Parallel或G1。 • 超大内存需求:ZGC。

(二)调整堆大小

通过-Xms和-Xmx参数合理配置堆内存大小,减少垃圾回收频率。例如:

-Xms512m -Xmx4g

(三)监控与分析

使用工具(如VisualVM、JStat、GC日志)监控垃圾回收行为,分析GC日志,优化配置。例如:

-XX:+PrintGCDetails -Xloggc:gc.log

 (四)调整垃圾收集器参数

根据垃圾收集器的特性,调整相关参数以优化性能。例如: • G1收集器:

-XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:MaxGCPauseMillis=200

 • CMS收集器:

-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70

三、实战案例分析

(一)案例1:CMS收集器的调优

问题描述:某Web应用在高并发场景下,频繁触发Full GC,导致响应时间显著增加。

分析过程:

  1. 通过GC日志发现,老年代的内存使用率较高,CMS收集器的并发阶段耗时较长。

  2. 使用VisualVM监控内存使用情况,发现存在大量长生命周期的对象。

解决方案:

  1. 增加老年代的内存大小(-XX:MaxHeapSize)。

  2. 调整CMS收集器的触发阈值(-XX:CMSInitiatingOccupancyFraction=75)。

  3. 启用增量式并发收集(-XX:+CMSIncrementalMode)。

优化效果:调整后,Full GC的频率显著降低,应用响应时间恢复正常

(二)案例2:G1收集器的调优

问题描述:某大数据应用在运行过程中,频繁触发垃圾回收,导致停顿时间过长。

分析过程:

  1. 通过GC日志发现,G1收集器的Mixed GC阶段耗时较长。

  2. 使用JStat监控Region的使用情况,发现存在大量大对象。

解决方案:

  1. 增加堆内存大小(-Xmx)。

  2. 调整G1收集器的停顿时间目标(-XX:MaxGCPauseMillis=300)。

  3. 增加Region的大小(-XX:G1HeapRegionSize=32m)。

优化效果:调整后,垃圾回收的停顿时间显著降低,应用运行更加稳定。


四、高频面试问题总结(附答案要点)

1. 如何判断对象是否存活?

  • 可达性分析:通过GC Roots链是否可达,具体列举至少4种GC Roots类型

2. 四种引用类型的区别?

  • 强引用(Object obj = new Object()):宁可OOM也不回收

  • 软引用(SoftReference):内存不足时回收,适合缓存

  • 弱引用(WeakReference):下次GC必回收

  • 虚引用(PhantomReference):无法通过它访问对象,跟踪对象被回收的状态

3. CMS收集器的工作流程与优缺点?

  • 流程:初始标记(STW)→ 并发标记 → 重新标记(STW)→ 并发清除

  • 优点:低延迟

  • 缺点:内存碎片、CPU敏感、无法处理浮动垃圾

4. G1相比CMS的核心改进?

  • 分区模型:将堆划分为多个Region,避免全堆扫描

  • 可预测停顿:通过维护Region回收价值优先列表

  • 算法升级:整体标记-整理,局部复制算法避免碎片

5. 如何排查内存泄漏?

  • 步骤

    1. jps获取进程ID

    2. jstat -gcutil观察GC频率

    3. jmap -histo:live生成堆直方图

    4. jmap -dump导出堆转储文件

    5. MAT工具分析对象引用链


五、实战思考题

  1. 为什么新生代需要两个Survivor区? (答:解决复制算法空间浪费问题,单Survivor会导致每次复制后一半空间完全闲置)

  2. 为什么G1适合大堆场景? (答:Region划分可精准控制回收范围,避免全堆回收带来的长停顿)


延伸学习建议:结合JVM参数(-XX:+UseG1GC等)与GC日志分析工具(GCViewer)进行实践观测,理解不同收集器的行为差异。


http://www.ppmy.cn/embedded/164903.html

相关文章

mysql系列9—mysql的MVCC机制

背景 mysql提供了读未提交、读已提交、可重复读、串行化四种隔离级别,默认的隔离界别为可重复读。其中,不可重复度场景下,每次直接读取最新记录(即使事务未提交);串行化对于所有的读写都加锁,因此,对二者不…

数据中心储能蓄电池状态监测管理系统 组成架构介绍

安科瑞刘鸿鹏 摘要 随着数据中心对供电可靠性要求的提高,蓄电池储能系统成为关键的后备电源。本文探讨了蓄电池监测系统在数据中心储能系统中的重要性,分析了ABAT系列蓄电池在线监测系统的功能、技术特点及其应用优势。通过蓄电池监测系统的实施&#…

LangChain大模型应用开发:多模态输入与自定义输出

介绍 大家好,博主又来给大家分享知识了。今天给大家分享的内容是使用LangChain进行大模型应用开发中的多模态输入与自定义输出。 LangChain中的多模态数据输入是指将多种不同形式的数据作为输入提供给基于语言模型的应用程序或系统,以丰富交互内容和提…

C++栈与队列:数据结构的“单行道”与“流水线

C栈与队列:数据结构的“单行道”与“流水线” 开篇小故事:火车站的两条轨道 想象一个火车站有两条特殊轨道: 轨道A(栈):火车只能从同一端进出,最后进入的车厢必须先离开。轨道B(队…

Win11更新系统c盘爆满处理

1.打开磁盘管理 2.右击c盘选择属性,进行磁盘管理,选择详细信息。 3.选择以前安装的文件删除即可释放c盘空间。

Java 集合:单列集合和双列集合的深度剖析

引言 在 Java 编程中,集合是一个非常重要的概念。它就像是一个容器,能够存储多个数据元素,帮助我们更方便地管理和操作数据。Java 集合框架主要分为单列集合和双列集合两大类,它们各自有着独特的特点和适用场景。接下来&#xff0…

全面汇总windows进程通信(二)

在Windows操作系统下,实现进程间通信(IPC, Inter-Process Communication)有几种常见的方法,包括使用管道(Pipe)、共享内存(Shared Memory)、消息队列(Message Queue)、命名管道(Named Pipe)、套接字(Socket)等。本文介绍如下几种: 信号量(Semaphore)和互斥量(…

ip归属地和手机卡有关系吗?详细探析

在数字化浪潮席卷全球的今天,互联网已成为连接世界的桥梁。IP地址,作为网络世界中每个设备的“身份证”,承载着设备的位置信息和通信功能。而手机卡,则是我们移动设备接入互联网的钥匙,它让随时随地的在线交流成为可能…