Java虚拟机之垃圾收集(一)
目录
一、如何判定对象“生死”?
1. 引用计数算法(理论参考)
2. 可达性分析算法(JVM 实际使用)
3. 对象的“缓刑”机制
二、引用类型与回收策略
三、何时触发垃圾回收?
1. 分代回收策略
2. 手动触发与注意事项
四、垃圾回收算法与实现
1. 基础算法对比
2. 分代收集理论
3. 新生代回收:Apple式复制算法
五、主流垃圾收集器详解
1. CMS 收集器(低停顿优先)
2. G1 收集器(平衡吞吐与延迟)
3. 收集器对比
六、调优建议与工具推荐
1. 参数配置示例
2. 常见问题排查
3. 工具推荐
七、总结
一、如何判定对象“生死”?
垃圾收集(GC)的核心是识别无用对象。JVM 通过两种算法判断对象是否存活:
1. 引用计数算法(理论参考)
-  原理: 
 每个对象维护一个引用计数器,被引用时计数器 +1,引用失效时 -1。计数器为 0 时判定为可回收。
-  缺点: 
 无法解决循环引用问题(如对象 A 引用 B,B 也引用 A)。
-  Java 未采用:主流 JVM 均使用 可达性分析算法。 
2. 可达性分析算法(JVM 实际使用)
-  原理: 
 从 GC Roots 出发,遍历对象引用链。若对象无法被 GC Roots 关联,则判定为可回收。
-  GC Roots 对象类型: -  虚拟机栈中的局部变量(如方法参数、局部变量)。 
-  方法区中静态变量引用的对象。 
-  方法区中常量引用的对象(如字符串常量池)。 
-  本地方法栈中 JNI 引用的对象(Native 方法)。 
-  同步锁持有的对象( synchronized锁对象)。
-  Java 虚拟机内部对象(如系统类加载器、异常对象)。 
 
-  
3. 对象的“缓刑”机制
-  finalize()方法:
 若对象重写finalize()且未被调用过,JVM 会将其放入F-Queue,由 Finalizer 线程触发该方法。
-  逃脱机会: 
 在finalize()中重新建立与 GC Roots 的引用链,可避免被回收(仅一次)。
public class RescueObject {public static RescueObject hook;@Overrideprotected void finalize() throws Throwable {super.finalize();hook = this; // 在 finalize 中自我拯救}
}二、引用类型与回收策略
Java 提供 四种引用类型,控制对象生命周期与回收优先级:
| 引用类型 | 特点 | 回收时机 | 典型场景 | 
|---|---|---|---|
| 强引用 | Object obj = new Object(),默认引用类型 | 对象不可达时回收 | 普通对象创建 | 
| 软引用 | SoftReference<Object> ref = new SoftReference<>(obj) | 内存不足时回收(OOM 前触发) | 缓存(如图片缓存) | 
| 弱引用 | WeakReference<Object> ref = new WeakReference<>(obj) | 下一次 GC 时回收 | 临时缓存(如 WeakHashMap) | 
| 虚引用 | PhantomReference<Object> ref = new PhantomReference<>(obj, queue) | 随时可能回收,需配合 ReferenceQueue 使用 | 堆外内存回收监听(如 DirectByteBuffer) | 
三、何时触发垃圾回收?
GC 触发时机由 内存区域分配策略 和 JVM 配置参数 共同决定:
1. 分代回收策略
| 区域 | GC 类型 | 触发条件 | 
|---|---|---|
| 新生代 | Minor GC | Eden 区空间不足 | 
| 老年代 | Major GC | 老年代空间不足(通常伴随 Full GC) | 
| 整堆 | Full GC | 方法区不足、老年代空间不足、手动调用 System.gc() | 
2. 手动触发与注意事项
-  System.gc():建议 JVM 触发 Full GC(不保证立即执行)。
-  风险:频繁 Full GC 会导致应用停顿(Stop-The-World),需谨慎使用。 
四、垃圾回收算法与实现
1. 基础算法对比
| 算法 | 步骤 | 优点 | 缺点 | 适用场景 | 
|---|---|---|---|---|
| 标记-清除 | 标记存活对象 → 清除未标记对象 | 简单 | 内存碎片化 | 老年代(CMS) | 
| 复制算法 | 存活对象复制到新区域 → 清空原区域 | 无碎片,高效 | 内存利用率 50% | 新生代(Survivor) | 
| 标记-整理 | 标记存活对象 → 整理到内存一端 | 无碎片化 | 整理耗时 | 老年代(Serial Old) | 
2. 分代收集理论
-  弱分代假说:绝大多数对象朝生夕灭(新生代)。 
-  强分代假说:熬过多次 GC 的对象难以消亡(老年代)。 
-  分代设计: -  新生代:使用复制算法(Eden + Survivor)。 
-  老年代:使用标记-清除或标记-整理算法。 
 
-  
3. 新生代回收:Apple式复制算法
-  内存划分: -  Eden : Survivor1 : Survivor2 = 8:1:1(默认)。 
 
-  
-  回收流程: -  新对象分配至 Eden 区。 
-  Eden 满时触发 Minor GC,存活对象复制到 Survivor1。 
-  下次 Minor GC 时,Eden 和 Survivor1 存活对象复制到 Survivor2,并清空原区域。 
-  对象年龄达到阈值(默认 15)后晋升老年代。 
 
-  
五、主流垃圾收集器详解
1. CMS 收集器(低停顿优先)
-  目标:最小化应用停顿时间。 
-  算法:标记-清除。 
-  工作流程: -  初始标记(STW):标记 GC Roots 直接关联对象。 
-  并发标记:遍历对象图(与用户线程并发)。 
-  重新标记(STW):修正并发标记期间变动的引用。 
-  并发清除:清理垃圾(与用户线程并发)。 
 
-  
-  缺点: -  内存碎片化(需定期 Full GC 整理)。 
-  并发阶段占用 CPU 资源。 
 
-  
2. G1 收集器(平衡吞吐与延迟)
-  目标:可预测的停顿时间(如 200ms 内)。 
-  内存布局:将堆划分为多个 Region(默认 2048 个)。 
-  工作流程: -  初始标记(STW):标记 GC Roots 直接关联对象。 
-  并发标记:遍历对象图(与用户线程并发)。 
-  最终标记(STW):处理剩余引用变更。 
-  筛选回收(STW):选择性价比高的 Region 回收。 
 
-  
-  优势: -  支持大内存(TB 级)。 
-  通过 Region 划分减少碎片化。 
 
-  
3. 收集器对比
| 收集器 | 算法 | 区域 | 特点 | 适用场景 | 
|---|---|---|---|---|
| CMS | 标记-清除 | 老年代 | 低停顿,但碎片化严重 | 响应敏感型应用 | 
| G1 | 标记-整理 | 全堆 | 可预测停顿,兼顾吞吐与延迟 | 大内存、低延迟应用 | 
六、调优建议与工具推荐
1. 参数配置示例
# 使用 G1 收集器,堆内存 4G,目标停顿 200ms
java -Xmx4G -Xms4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar# 启用 CMS 收集器
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode2. 常见问题排查
-  频繁 Full GC: -  检查内存泄漏(如静态集合未清理)。 
-  调整新生代与老年代比例( -XX:NewRatio)。
 
-  
-  长时间 STW: -  切换低延迟收集器(如 G1/ZGC)。 
-  减少堆内存大小(权衡吞吐与停顿)。 
 
-  
3. 工具推荐
-  监控工具:VisualVM、JConsole、Prometheus + Grafana。 
-  日志分析:GCeasy、GCViewer。 
-  诊断工具:Arthas、MAT(Memory Analyzer Tool)。 
七、总结
-  生死判定:可达性分析是核心, finalize()是最后的逃生机会。
-  引用分级:软、弱引用优化内存敏感场景。 
-  算法选择:分代理论平衡效率与资源利用率。 
-  收集器选型:CMS 适合低延迟,G1 适合大内存与可预测停顿。 
核心原则:结合业务需求与监控数据动态调优,避免盲目配置。
相关文章:
Java虚拟机之垃圾收集(一)
目录 一、如何判定对象“生死”? 1. 引用计数算法(理论参考) 2. 可达性分析算法(JVM 实际使用) 3. 对象的“缓刑”机制 二、引用类型与回收策略 三、何时触发垃圾回收? 1. 分代回收策略 2. 手动触发…...
linux---天气爬虫
代码概述 这段代码实现了一个天气查询系统,支持实时天气、未来天气和历史天气查询。用户可以通过终端菜单选择查询类型,并输入城市名称来获取相应的天气信息。程序通过 TCP 连接发送 HTTP 请求,并解析返回的 JSON 数据来展示天气信息。 #in…...
 
字节顺序(大小端序)
在弄明白字节顺序之前先了解一下一些基础概念. 基础概念 字节(byte): 字节是计算机中数据处理的基本单位,通常由8个位组成,即1字节等于8位。一个字节可以存储一个ASCII码,两个字节可以存放一个汉字国标…...
可复用的 Vue 轮播图组件
大家好,今天我想和大家分享一下如何开发一个通用的 Vue 轮播图组件。轮播图在各种网站中都很常见,无论是展示产品、活动还是文章,都能派上用场。我们今天要实现的这个组件会具备良好的可配置性和易用性,同时保证代码的可维护性。 …...
 
AI编程: 一个案例对比CPU和GPU在深度学习方面的性能差异
背景 字节跳动正式发布中国首个AI原生集成开发环境工具(AI IDE)——AI编程工具Trae国内版。 该工具模型搭载doubao-1.5-pro,支持切换满血版DeepSeek R1&V3, 可以帮助各阶段开发者与AI流畅协作,更快、更高质量地完…...
 
Linux红帽:RHCSA认证知识讲解(五)从红帽和 DNF 软件仓库下载、安装、更新和管理软件包
Linux红帽:RHCSA认证知识讲解(五)从红帽和 DNF 软件仓库下载、安装、更新和管理软件包 前言一、DNF 软件包管理基础1.1 核心操作命令安装软件包卸载软件包重新安装软件包 1.2 软件仓库原理 二、配置自定义软件仓库步骤 1:清理默认…...
云上特权凭证攻防启示录:从根账号AK泄露到安全体系升级的深度实践
事件全景:一场持续17分钟的云上攻防战 2025年3月9日15:39,阿里云ActionTrail日志突现异常波纹——根账号acs:ram::123456789:root(已脱敏)从立陶宛IP(164.92.91.227)发起高危操作。攻击者利用泄露的AccessKey(AK)在17分钟内完成侦察→提权→持久化攻击链,完整操作序列…...
从3b1b到课堂:教育3D化的理想与现实鸿沟
从3b1b到课堂:教育3D化的理想与现实鸿沟 3Blue1Brown(3b1b)凭借精妙的三维动画与直观的知识可视化,重新定义了数学教育的可能性。然而,当前教育实践中,3D技术的渗透仍显不足,多数课堂停留在平面…...
FPGA入门教程
引言 FPGA(Field-Programmable Gate Array,现场可编程门阵列)是一种灵活且强大的硬件设备,广泛应用于数字电路设计、信号处理、嵌入式系统等领域。与传统的ASIC(专用集成电路)不同,FPGA允许用户…...
 
Liunx系统 : 进程间通信【IPC-Shm共享内存】
文章目录 System V共享内存创建共享内存shmget 控制共享内存shmctl shm特性 System V System V是Liunx中的重要的进程间通信机制,它包括(shm)共享内存,(msg)消息队列和(sem)信号量。…...
KafkaRocketMQ
Kafka 消息生产与消费流程 1. 消息生产 生产者创建消息: 指定目标 Topic、Key(可选)、Value。可附加 Header 信息(如时间戳、自定义元数据)。 选择分区(Partition): 若指定 Key&am…...
 
HarmonyOS Next 中的状态管理
在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkU…...
 
基于qiime2的16S数据分析全流程:从导入数据到下游分析一条龙
目录 创建metadata 把数据导入qiime2 去除引物序列 双端合并 (dada2不需要) 质控 (dada2不需要) 使用deblur获得特征序列 使用dada2生成代表序列与特征表 物种鉴定 可视化物种鉴定结果 构建进化树(ITS一般不构建进化树…...
【软件测试开发】:软件测试常用函数1.0(C++)
1. 元素的定位 web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作。 常⻅的元素定位⽅式⾮常多,如id,classname,tagname,xpath,cssSelector 常⽤的主要由cssSelector和xpath…...
 
vue2项目修改浏览器显示的网页图标
1.准备一个新的图标文件,通常是. ico格式,也可以是. Png、. Svg等格式 2.将新的图标文件(例如:faviconAt.png)放入项目的public文件夹中。如下图 public文件夹中的所有文件都会在构建时原样复制到最终的输出目录(通常是dist) 3. 修改vue项目…...
 
开源、创新与人才发展:机器人产业的战略布局与稚晖君成功案例解析
目录 引言 一、开源:机器人产业的战略布局 促进技术进步和生态建设 吸引人才和合作伙伴 建立标准和网络效应 降低研发风险与成本 二、稚晖君:华为"天才少年计划"的成功典范 深厚的技术积累与动手能力 强烈的探索和创新意识 持续公开…...
 
线程相关作业
1.创建两个线程,分支线程1拷贝文件的前一部分,分支线程2拷贝文件的后一部分 #include "head.h"#define BUFFER_SIZE 1024// 线程参数结构体,包含文件名和文件偏移量 typedef struct {FILE *src_file;FILE *dest_file;long start_o…...
 
通义万相2.1开源版本地化部署攻略,生成视频再填利器
2025 年 2 月 25 日晚上 11:00 通义万相 2.1 开源发布,前两周太忙没空搞它,这个周末,也来本地化部署一个,体验生成效果如何,总的来说,它在国内文生视频、图生视频的行列处于领先位置,…...
 
【模拟CMOS集成电路设计】带隙基准(Bandgap)设计与仿真(基于运放的电流模BGR)
【模拟CMOS集成电路设计】带隙基准(Bandgap)设计与仿真 前言工程文件&部分参数计算过程,私聊~ 一、 设计指标指标分析: 二、 电路分析三、 仿真3.1仿真电路图3.2仿真结果(1)运放增益(2)基准温度系数仿真(3)瞬态启动仿真(4)静态…...
 
如何选择国产串口屏?
目录 1、迪文 2、淘晶驰 3、广州大彩 4、金玺智控 5、欣瑞达 6、富莱新 7、冠显 8、有彩 串口屏,顾名思义,就是通过串口通信接口(如RS232、RS485、TTL UART等)与主控设备进行通信的显示屏。其核心功能是显示信息和接收输入…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
 
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
 
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
 
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
 
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
 
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
