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

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 GCEden 区空间不足
老年代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(默认)。

  • 回收流程

    1. 新对象分配至 Eden 区。

    2. Eden 满时触发 Minor GC,存活对象复制到 Survivor1。

    3. 下次 Minor GC 时,Eden 和 Survivor1 存活对象复制到 Survivor2,并清空原区域。

    4. 对象年龄达到阈值(默认 15)后晋升老年代。


五、主流垃圾收集器详解

1. CMS 收集器(低停顿优先)

  • 目标:最小化应用停顿时间。

  • 算法:标记-清除。

  • 工作流程

    1. 初始标记(STW):标记 GC Roots 直接关联对象。

    2. 并发标记:遍历对象图(与用户线程并发)。

    3. 重新标记(STW):修正并发标记期间变动的引用。

    4. 并发清除:清理垃圾(与用户线程并发)。

  • 缺点

    • 内存碎片化(需定期 Full GC 整理)。

    • 并发阶段占用 CPU 资源。

2. G1 收集器(平衡吞吐与延迟)

  • 目标:可预测的停顿时间(如 200ms 内)。

  • 内存布局:将堆划分为多个 Region(默认 2048 个)。

  • 工作流程

    1. 初始标记(STW):标记 GC Roots 直接关联对象。

    2. 并发标记:遍历对象图(与用户线程并发)。

    3. 最终标记(STW):处理剩余引用变更。

    4. 筛选回收(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:+CMSIncrementalMode

2. 常见问题排查

  • 频繁 Full GC

    • 检查内存泄漏(如静态集合未清理)。

    • 调整新生代与老年代比例(-XX:NewRatio)。

  • 长时间 STW

    • 切换低延迟收集器(如 G1/ZGC)。

    • 减少堆内存大小(权衡吞吐与停顿)。

3. 工具推荐

  • 监控工具:VisualVM、JConsole、Prometheus + Grafana。

  • 日志分析:GCeasy、GCViewer。

  • 诊断工具:Arthas、MAT(Memory Analyzer Tool)。


七、总结

  • 生死判定:可达性分析是核心,finalize() 是最后的逃生机会。

  • 引用分级:软、弱引用优化内存敏感场景。

  • 算法选择:分代理论平衡效率与资源利用率。

  • 收集器选型:CMS 适合低延迟,G1 适合大内存与可预测停顿。

核心原则:结合业务需求与监控数据动态调优,避免盲目配置。

相关文章:

Java虚拟机之垃圾收集(一)

目录 一、如何判定对象“生死”&#xff1f; 1. 引用计数算法&#xff08;理论参考&#xff09; 2. 可达性分析算法&#xff08;JVM 实际使用&#xff09; 3. 对象的“缓刑”机制 二、引用类型与回收策略 三、何时触发垃圾回收&#xff1f; 1. 分代回收策略 2. 手动触发…...

linux---天气爬虫

代码概述 这段代码实现了一个天气查询系统&#xff0c;支持实时天气、未来天气和历史天气查询。用户可以通过终端菜单选择查询类型&#xff0c;并输入城市名称来获取相应的天气信息。程序通过 TCP 连接发送 HTTP 请求&#xff0c;并解析返回的 JSON 数据来展示天气信息。 #in…...

字节顺序(大小端序)

在弄明白字节顺序之前先了解一下一些基础概念. 基础概念 字节&#xff08;byte&#xff09;‌&#xff1a; 字节是计算机中数据处理的基本单位&#xff0c;通常由8个位组成&#xff0c;即1字节等于8位。一个字节可以存储一个ASCII码&#xff0c;两个字节可以存放一个汉字国标…...

可复用的 Vue 轮播图组件

大家好&#xff0c;今天我想和大家分享一下如何开发一个通用的 Vue 轮播图组件。轮播图在各种网站中都很常见&#xff0c;无论是展示产品、活动还是文章&#xff0c;都能派上用场。我们今天要实现的这个组件会具备良好的可配置性和易用性&#xff0c;同时保证代码的可维护性。 …...

AI编程: 一个案例对比CPU和GPU在深度学习方面的性能差异

背景 字节跳动正式发布中国首个AI原生集成开发环境工具&#xff08;AI IDE&#xff09;——AI编程工具Trae国内版。 该工具模型搭载doubao-1.5-pro&#xff0c;支持切换满血版DeepSeek R1&V3&#xff0c; 可以帮助各阶段开发者与AI流畅协作&#xff0c;更快、更高质量地完…...

Linux红帽:RHCSA认证知识讲解(五)从红帽和 DNF 软件仓库下载、安装、更新和管理软件包

Linux红帽&#xff1a;RHCSA认证知识讲解&#xff08;五&#xff09;从红帽和 DNF 软件仓库下载、安装、更新和管理软件包 前言一、DNF 软件包管理基础1.1 核心操作命令安装软件包卸载软件包重新安装软件包 1.2 软件仓库原理 二、配置自定义软件仓库步骤 1&#xff1a;清理默认…...

云上特权凭证攻防启示录:从根账号AK泄露到安全体系升级的深度实践

事件全景:一场持续17分钟的云上攻防战 2025年3月9日15:39,阿里云ActionTrail日志突现异常波纹——根账号acs:ram::123456789:root(已脱敏)从立陶宛IP(164.92.91.227)发起高危操作。攻击者利用泄露的AccessKey(AK)在17分钟内完成侦察→提权→持久化攻击链,完整操作序列…...

从3b1b到课堂:教育3D化的理想与现实鸿沟

从3b1b到课堂&#xff1a;教育3D化的理想与现实鸿沟 3Blue1Brown&#xff08;3b1b&#xff09;凭借精妙的三维动画与直观的知识可视化&#xff0c;重新定义了数学教育的可能性。然而&#xff0c;当前教育实践中&#xff0c;3D技术的渗透仍显不足&#xff0c;多数课堂停留在平面…...

FPGA入门教程

引言 FPGA&#xff08;Field-Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;是一种灵活且强大的硬件设备&#xff0c;广泛应用于数字电路设计、信号处理、嵌入式系统等领域。与传统的ASIC&#xff08;专用集成电路&#xff09;不同&#xff0c;FPGA允许用户…...

Liunx系统 : 进程间通信【IPC-Shm共享内存】

文章目录 System V共享内存创建共享内存shmget 控制共享内存shmctl shm特性 System V System V是Liunx中的重要的进程间通信机制&#xff0c;它包括&#xff08;shm&#xff09;共享内存&#xff0c;&#xff08;msg&#xff09;消息队列和&#xff08;sem&#xff09;信号量。…...

KafkaRocketMQ

Kafka 消息生产与消费流程 1. 消息生产 生产者创建消息&#xff1a; 指定目标 Topic、Key&#xff08;可选&#xff09;、Value。可附加 Header 信息&#xff08;如时间戳、自定义元数据&#xff09;。 选择分区&#xff08;Partition&#xff09;&#xff1a; 若指定 Key&am…...

HarmonyOS Next 中的状态管理

在声明式UI编程框架中&#xff0c;UI是程序状态的运行结果&#xff0c;用户构建了一个UI模型&#xff0c;其中应用的运行时的状态是参数。当参数改变时&#xff0c;UI作为返回结果&#xff0c;也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染&#xff0c;在ArkU…...

基于qiime2的16S数据分析全流程:从导入数据到下游分析一条龙

目录 创建metadata 把数据导入qiime2 去除引物序列 双端合并 &#xff08;dada2不需要&#xff09; 质控 &#xff08;dada2不需要&#xff09; 使用deblur获得特征序列 使用dada2生成代表序列与特征表 物种鉴定 可视化物种鉴定结果 构建进化树&#xff08;ITS一般不构建进化树…...

【软件测试开发】:软件测试常用函数1.0(C++)

1. 元素的定位 web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素&#xff0c;然后才能对元素进⾏具体的操作。 常⻅的元素定位⽅式⾮常多&#xff0c;如id&#xff0c;classname&#xff0c;tagname&#xff0c;xpath&#xff0c;cssSelector 常⽤的主要由cssSelector和xpath…...

vue2项目修改浏览器显示的网页图标

1.准备一个新的图标文件&#xff0c;通常是. ico格式&#xff0c;也可以是. Png、. Svg等格式 2.将新的图标文件(例如&#xff1a;faviconAt.png)放入项目的public文件夹中。如下图 public文件夹中的所有文件都会在构建时原样复制到最终的输出目录(通常是dist) 3. 修改vue项目…...

开源、创新与人才发展:机器人产业的战略布局与稚晖君成功案例解析

目录 引言 一、开源&#xff1a;机器人产业的战略布局 促进技术进步和生态建设 吸引人才和合作伙伴 建立标准和网络效应 降低研发风险与成本 二、稚晖君&#xff1a;华为"天才少年计划"的成功典范 深厚的技术积累与动手能力 强烈的探索和创新意识 持续公开…...

线程相关作业

1.创建两个线程&#xff0c;分支线程1拷贝文件的前一部分&#xff0c;分支线程2拷贝文件的后一部分 #include "head.h"#define BUFFER_SIZE 1024// 线程参数结构体&#xff0c;包含文件名和文件偏移量 typedef struct {FILE *src_file;FILE *dest_file;long start_o…...

通义万相2.1开源版本地化部署攻略,生成视频再填利器

2025 年 2 月 25 日晚上 11&#xff1a;00 通义万相 2.1 开源发布&#xff0c;前两周太忙没空搞它&#xff0c;这个周末&#xff0c;也来本地化部署一个&#xff0c;体验生成效果如何&#xff0c;总的来说&#xff0c;它在国内文生视频、图生视频的行列处于领先位置&#xff0c…...

【模拟CMOS集成电路设计】带隙基准(Bandgap)设计与仿真(基于运放的电流模BGR)

【模拟CMOS集成电路设计】带隙基准&#xff08;Bandgap&#xff09;设计与仿真 前言工程文件&部分参数计算过程&#xff0c;私聊~ 一、 设计指标指标分析&#xff1a; 二、 电路分析三、 仿真3.1仿真电路图3.2仿真结果(1)运放增益(2)基准温度系数仿真(3)瞬态启动仿真(4)静态…...

如何选择国产串口屏?

目录 1、迪文 2、淘晶驰 3、广州大彩 4、金玺智控 5、欣瑞达 6、富莱新 7、冠显 8、有彩 串口屏&#xff0c;顾名思义&#xff0c;就是通过串口通信接口&#xff08;如RS232、RS485、TTL UART等&#xff09;与主控设备进行通信的显示屏。其核心功能是显示信息和接收输入…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

Java并发编程实战 Day 11:并发设计模式

【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天&#xff0c;今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案&#xff0c;它们不仅提供了优雅的设计思路&#xff0c;还能显著提升系统的性能…...