垃圾收集技术详解笔记

1. 分代收集理论

当前虚拟机的垃圾收集采用分代收集算法,根据对象存活周期将内存分为不同代区,以优化回收效率。

  • 核心分区
    • 新生代(Young Generation):对象存活周期短,约99%对象在每次回收时死亡。
    • 老年代(Old Generation):对象存活率高,无额外分配担保空间。
  • 算法选择
    • 新生代:适用复制算法(效率高,只需复制少量存活对象)。
    • 老年代:适用标记-清除或标记-整理算法(避免复制开销,但速度慢10倍以上)。
2. 垃圾收集算法详解
2.1 标记-复制算法

解决效率问题,将内存分为大小相等的两块。

  • 工作流程
    1. 使用其中一块内存。
    2. 当内存耗尽,将存活对象复制到另一块。
    3. 清理原内存块。
  • 内存变化示例
    • 整理前:碎片化状态。
    • 整理后:存活对象集中到另一块,内存连续。
  • 内存区域类型
    • 可用内存、可回收内存、存活对象、保留内存。
2.2 标记-清除算法

最基础算法,分“标记”和“清除”两阶段。

  • 工作流程
    • 标记存活对象(或需回收对象)。
    • 清除未标记对象。
  • 缺点
    • 效率问题:标记大量对象时性能低。
    • 空间问题:产生内存碎片(不连续空间)。
  • 内存变化示例
    • 整理前:碎片化状态。
    • 整理后:碎片化更严重,仅区分可用内存、可回收内存、存活对象。
2.3 标记-整理算法

专为老年代设计,标记后移动对象以消除碎片。

  • 工作流程
    1. 标记存活对象。
    2. 将所有存活对象向一端移动。
    3. 清理边界外内存。
  • 内存变化示例
    • 回收前:碎片化状态。
    • 回收后:对象紧凑排列,区分存活对象、可回收内存、未使用内存。
3. 垃圾收集器实现

收集器是算法的具体实现,需根据场景选择。无“万能”收集器。

3.1 Serial收集器(-XX:+UseSerialGC, -XX:+UseSerialOldGC)
  • 特点
    • 单线程收集器,工作时暂停所有线程(Stop The World)。
    • 简单高效(无线程交互开销)。
  • 算法
    • 新生代:复制算法。
    • 老年代:标记-整理算法。
  • 适用场景:客户端模式或小内存应用。
3.2 Parallel Scavenge收集器(-XX:+UseParallelGC, -XX:+UseParallelOldGC)
  • 特点
    • Serial的多线程版本(默认线程数 = CPU核数)。
    • 关注吞吐量(CPU运行用户代码时间占比)。
  • 算法
    • 新生代:复制算法。
    • 老年代:标记-整理算法。
  • Parallel Old收集器
    • Parallel Scavenge的老年代版本,多线程 + 标记-整理算法。
    • JDK8默认收集器,适合高吞吐场景。
3.3 ParNew收集器(-XX:+UseParNewGC)
  • 特点
    • 类似Parallel,但专为与CMS收集器配合设计。
    • 新生代使用复制算法。
  • 适用场景:Server模式下的首选(与CMS兼容)。
3.4 CMS收集器(-XX:+UseConcMarkSweepGC)
  • 特点
    • 并发收集器(最短停顿时间),用户线程与GC线程并行。
    • 基于标记-清除算法。
  • 工作流程
    1. 初始标记(STW):标记GC Roots直接引用对象。
    2. 并发标记:遍历对象图(无停顿)。
    3. 重新标记(STW):修正并发标记变动(用增量更新算法)。
    4. 并发清理:清除未标记对象。
    5. 并发重置:重置标记数据。
  • 缺点
    • CPU敏感(与业务线程抢资源)。
    • 浮动垃圾(并发阶段新垃圾需下次回收)。
    • 内存碎片(需定期整理)。
    • 不确定性(可能触发Concurrent Mode Failure,降级为Serial Old)。
  • 关键参数
    -XX:+UseConcMarkSweepGC     # 启用CMS  
    -XX:ConcGCThreads            # 并发GC线程数  
    -XX:+UseCMSCompactAtFullCollection  # FullGC后整理碎片  
    -XX:CMSFullGCsBeforeCompaction       # 多少次FullGC后整理一次(默认0)  
    -XX:CMSInitiatingOccupancyFraction   # 老年代使用比例触发FullGC(默认92%)  
    -XX:+CMSScavengeBeforeRemark         # CMS前启动Minor GC  
    
4. 亿级流量电商系统JVM优化案例

针对订单系统(8G内存,分配4G给JVM)。

  • 优化目标:减少Full GC(避免对象过早进入老年代)。
  • 参数配置
    -Xms3072M -Xmx3072M -Xmn2048M   # 堆大小(新生代2G)  
    -Xss1M                          # 线程栈大小  
    -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M  # 元空间  
    -XX:SurvivorRatio=8             # Eden与Survivor比例  
    -XX:MaxTenuringThreshold=5      # 对象年龄阈值(从15改为5)  
    -XX:PretenureSizeThreshold=1M   # 直接进入老年代对象大小阈值  
    -XX:+UseParNewGC -XX:+UseConcMarkSweepGC  # 新生代ParNew + 老年代CMS  
    -XX:CMSInitiatingOccupancyFraction=92     # 老年代92%触发FullGC  
    -XX:+UseCMSCompactAtFullCollection        # FullGC后整理碎片  
    -XX:CMSFullGCsBeforeCompaction=3          # 每3次FullGC整理一次  
    
  • 优化原理
    • 增大新生代(-Xmn2048M),减少对象动态年龄判断导致的过早晋升。
    • 降低对象年龄阈值(-XX:MaxTenuringThreshold=5),确保短期对象在Minor GC回收。
    • CMS默认参数适合高峰后Full GC(几小时一次)。
5. 垃圾收集底层算法
5.1 三色标记算法

解决并发标记中的漏标问题,将对象分为三色:

  • 黑色:已扫描完(安全存活)。
  • 灰色:已扫描,但引用未全扫描。
  • 白色:未扫描(不可达对象)。
  • 问题与解决
    • 多标(浮动垃圾):并发阶段局部变量销毁导致本应回收的对象未被回收(下一轮GC处理)。
    • 漏标:通过读写屏障解决:
      • 增量更新(CMS使用):黑色对象插入新引用时记录,重新扫描。
      • 原始快照(SATB, G1使用):灰色对象删除引用时记录,重新扫描。
  • 读写屏障实现
    // 写屏障示例(增量更新)  
    void oop_field_store(oop* field, oop new_value) {pre_write_barrier(field);    // 写前操作(记录旧值)*field = new_value;post_write_barrier(field, new_value); // 写后操作(记录新值)
    }
    
5.2 记忆集与卡表

解决跨代引用问题(如新生代引用老年代)。

  • 记忆集(Remember Set):记录跨代指针集合。
  • 卡表实现:字节数组(CARD_TABLE[]),每卡页512字节。
    • 卡页变脏(=1):有跨代指针时更新。
  • 维护:通过写屏障自动更新卡表状态。
6. 总结
  • 分代收集是JVM垃圾回收核心,新生代和老年代需匹配不同算法。
  • 收集器选择需权衡吞吐量(Parallel Scavenge)和停顿时间(CMS)。
  • 优化案例显示:合理配置新生代大小、对象年龄阈值及CMS参数可显著减少Full GC。
  • 底层算法(三色标记、读写屏障)确保并发标记的正确性,避免漏标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/91629.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/91629.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/91629.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全排列(回溯算法)

本文参考代码随想录 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 思路 排列是有序的,在排列问题中不需要startIndex;但排列问题需要一个…

在线任意长度大整数计算器

具体请前往:在线大整数计算器--支持超大整数的加减乘除,幂运算/模运算,最大公约数,最小公倍数

AT6668B芯片说明书

这颗北斗专用单芯片解决方案AT6668B,采用射频前端与基带处理一体化设计,集成北斗二号/三号双模B1IB1C信号处理器。通过优化星历解码算法实现秒级卫星锁定,配合硬件加速的干扰监测模块,在电磁环境复杂的应用场景中仍可维持10Hz高频…

谷歌Chrome浏览器安装插件

因为google浏览器的应用市场(https://chrome.google.com/webstore/category/extensions)在国内无法访问,所以无法在线安装插件,这里提供开发者模式离线安装插件的方法。 1、下载crx脚本 谷歌浏览器的插件离线文件的扩展名为:crx(Firefox火狐浏览器的插件扩展名为fpi)。…

【制造】erp和mes系统建设方案(word)

第一部分 概述 第二部分 方案介绍 第三部分 系统业务流程 3.1 关键需求概括分析 3.1.1 销售管理方面 3.1.2 采购管理方面 3.1.3 仓库管理方面 3.1.4 财务管理方面 3.1.5 人力资源方面 3.2 关键需求具体分析 3.2.1 财务管理 3.2.1.1会计凭证解决 3.2.1.2钞票流…

Spring AI 系列之二十八 - Spring AI Alibaba-基于Nacos的prompt模版

之前做个几个大模型的应用,都是使用Python语言,后来有一个项目使用了Java,并使用了Spring AI框架。随着Spring AI不断地完善,最近它发布了1.0正式版,意味着它已经能很好的作为企业级生产环境的使用。对于Java开发者来说…

IMAP电子邮件归档系统Mail-Archiver

简介 什么是 Mail-Archiver ? Mail-Archiver 是一个用于从多个 IMAP 账户归档、搜索和导出电子邮件的 web 应用程序。它提供了一种全面的解决方案,帮助用户管理和存储电子邮件。 主要特点 📌自动归档:自动归档进出邮件&#xff…

李宏毅深度学习教程 第6-7章 自注意力机制 + Transformer

强烈推荐!台大李宏毅自注意力机制和Transformer详解!_哔哩哔哩_bilibili 目录 1. 词嵌入&问题情形 2. self-attention 自注意力机制 3. 自注意力的变形 3.1 多头注意力(multi-head) 3.2 位置编码 3.3 截断自注意力&…

大模型幻觉的本质:深度=逻辑层次,宽度=组合限制,深度为n的神经网络最多只能处理n层逻辑推理,宽度为w的网络无法区分超过w+1个复杂对象的组合

大模型幻觉的本质:深度逻辑层次,宽度组合限制,深度为n的神经网络最多只能处理n层逻辑推理,宽度为w的网络无法区分超过w1个复杂对象的组合🧩 "深度逻辑层次"具体含义🔢 "宽度组合限制"具…

2419.按位与最大的最长子数组

Problem: 2419. 按位与最大的最长子数组 思路 子数组按位与的结果,不会超过子数组里的最大值(因为 a & b ≤ max(a, b))。 进一步推导,整个数组最大按位与的结果就是数组本身的最大值。 因为最大的那个元素自己作为子数组时&a…

智能时代:先管端点,再谈效率

为什么需要统一端点管理?在混合办公常态化、设备类型爆炸式增长的2025年,分散的端点如同散落各地的哨所。传统管理方式让IT团队疲于应对系统更新、漏洞修复、权限分配等重复劳动,不仅消耗60%以上的运维时间,更可能因响应延迟导致安…

Windows字体simsum.ttf的安装与Python路径设置指南

下载工具: https://fontforge.org/en-US/downloads/windows-dl/ 使用工具: 复制到c:\windows\fonts路径下面。 并复制到运行的python程序同一路径下。比如:c:\pythoncode\new\

GitHub下载项目完整配置SSH步骤详解

GitHub下载项目完整配置步骤(从零开始) 默认下好了git ,在文件夹中右键打开git bash , 如果没有请在csdn搜索教程 第一步:检查并清理现有SSH配置 # 进入.ssh目录 cd ~/.ssh# 备份并删除所有现有密钥(避免冲…

数据结构(9)栈和队列

1、栈 1.1 概念与结构 栈是一种特殊的线性表,只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除的一端称为栈顶,另一端称为栈底。栈里面的数据元素遵循后进先出的原则。栈的底层实现一般可以使用数组或者链表来实现,但数组的…

湖北大学暑期实训优秀作品:面向美丽中国的数据化可视平台

开发背景2024年1月11日,《中共中央国务院关于全面推进美丽中国建设的意见》发布,明确了建设美丽中国的总体要求、主要目标和重点任务,为我国生态文明建设提供了顶层设计和行动指南。系统简介当前,中国正以空前的力度推进生态文明建…

Ubuntu系统VScode实现opencv(c++)随机数与随机颜色

在图像处理与计算机图形学中,随机数与随机颜色的生成常用于增强图像的多样性、可视化多个目标区域、模拟自然现象以及生成测试数据等任务。通过随机化元素的颜色、位置或形状,可以使程序在动态展示、调试输出、以及数据增强等方面更加灵活和丰富。例如&a…

机器学习、深度学习与数据挖掘:三大技术领域的深度解析

基本概念与历史沿革数据挖掘起源于20世纪90年代,是数据库技术、统计学和机器学习交叉融合的产物。它经历了从简单查询到复杂知识发现的演变过程,早期阶段主要关注数据存储和检索,随着IBM、微软等公司的推动,逐渐形成了完整的知识发…

MoR vs MoE架构对比:更少参数、更快推理的大模型新选择

Google DeepMind 近期发布了关于递归混合(Mixture of Recursion)架构的研究论文,这一新型 Transformers 架构变体在学术界和工业界引起了广泛关注。该架构通过创新的设计理念,能够在保持模型性能的前提下显著降低推理延迟和模型规…

uniapp开发实现【中间放大两边缩小的轮播图】

一、效果展示 二、代码实现 <template><view><!-- 轮播图 --><view class=<

机器学习没有最好的模型,只有最合适的选择(模型选择)

机器学习领域存在"没有免费午餐"定理&#xff0c;没有任何一种模型在所有问题上都表现最优。不同模型有各自的优势和适用场景。同一数据集上&#xff0c;不同模型的预测性能可能有巨大差异。例如&#xff0c;线性关系明显的数据上线性模型可能表现优异&#xff0c;而…