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

垃圾回收算法与垃圾收集器

文章目录

  • 一、垃圾回收算法
    • 1. 标记-清除算法
    • 2. 复制算法
    • 3. 标记-整理算法
  • 二、垃圾收集器
    • 新生代收集器
      • 1. Serial收集器
      • 2. ParNew收集器
      • 3. Parallel Scavenge收集器
    • 老年代收集器
      • 1. Serial Old收集器
      • 2. Parallel Old收集器
      • 3. CMS收集器
    • G1收集器
      • 概念特点
      • G1的工作流程
      • G1的优势
  • 三、算法与收集器的对应关系

一、垃圾回收算法

1. 标记-清除算法

工作流程:

第一阶段:标记出所有需要回收的对象
第二阶段:清除统一回收所有被标记的对象

优缺点:

  • 优点:实现简单,适用于存活对象多的场景
  • 缺点:会产生内存碎片,效率不稳定

2. 复制算法

工作流程:

将内存分为两块相等区域
只使用其中一块,另一块闲置
GC时将存活对象复制到闲置区域
清空原使用区域,两块区域角色互换

优缺点:

  • 优点:无内存碎片,效率高
  • 缺点:浪费一半内存空间,以空间换时间

3. 标记-整理算法

工作流程:

第一阶段:标记所有存活对象
第二阶段:将存活对象向内存一端移动
第三阶段:清理掉边界以外的内存

优缺点:

  • 优点:无内存碎片,内存利用率高
  • 缺点:移动对象成本高,效率较低

二、垃圾收集器

新生代收集器

1. Serial收集器

特点:

  1. GC时会暂停所有用户线程(Stop The World)
  2. 单线程执行垃圾回收
  3. 回收完成后恢复用户线程

2. ParNew收集器

特点:

  1. 多线程并行收集
  2. 其他行为与Serial完全一样
  3. 常与CMS搭配使用

3. Parallel Scavenge收集器

特点:

  1. 可控制的吞吐量(运行代码时间/(运行代码时间+GC时间))
  2. 自适应调节策略
  3. 目标是达到可控的吞吐量

老年代收集器

1. Serial Old收集器

这是Serial收集器的老年代版本:

还是单线程工作
使用标记-整理算法
主要用在客户端程序上

2. Parallel Old收集器

这是Parallel Scavenge的搭档:

多线程并行工作
同样使用标记-整理算法
和Parallel Scavenge一起使用,整体注重吞吐量

3. CMS收集器

CMS全称是Concurrent Mark Sweep,意思是并发标记清除,这是个很有特色的收集器:
工作流程比较复杂:

初始标记:快速标记一下根源对象,这个过程需要暂停程序
并发标记:一边让程序正常跑,一边慢慢标记所有要清理的对象
重新标记:再暂停一下程序,修正错标、漏标的对象
并发清除:一边让程序跑,一边清理垃圾

CMS的缺点:

  1. 在并发标记阶段会和用户线程争抢CPU资源,影响用户线程的执行效率
  2. 清理过程中还在产生新垃圾(浮动垃圾),有些垃圾这次清理不了,得放到下一次GC
  3. 使用标记-清除算法,会产生内存碎片

G1收集器

概念特点

G1是Garbage First的缩写,这是目前比较先进的收集器:

  1. 把整个内存分成很多小块(Region),每块通常1-32MB
  2. 每个小块可以分别当作新生代或老年代来用
  3. 每次清理的时候,会根据垃圾最多、回收效益最高的的几个小块来清理

G1的工作流程

初始标记:快速标记根源对象,需要暂停程序
并发标记:程序正常跑的同时进行标记工作
最终标记:暂停程序,处理并发期间的变化
筛选回收:暂停程序,选择最值得清理的区域进行回收

G1的优势

  1. 可以设定目标暂停时间,比如希望每次暂停不超过200毫秒
  2. 内存利用率高,没有传统分代收集器的空间浪费
  3. GC时不会产生内存碎片
  4. 适合大内存应用,可以处理几个G到几十G的堆内存

三、算法与收集器的对应关系

收集器算法选择适用场景
Serial复制(新生代)单核CPU,小应用
ParNew复制(新生代)多核CPU,配合CMS
Parallel Scavenge复制(新生代)注重吞吐量
Serial Old标记-整理(老年代)单核CPU,小应用
Parallel Old标记-整理(老年代)注重吞吐量
CMS标记-清除(老年代)注重响应时间
G1复制+标记-整理大堆内存,低延迟要求
http://www.dtcms.com/a/299278.html

相关文章:

  • 数字迷雾中的安全锚点:解码匿名化与假名化的法律边界与商业价值
  • 深入解析三大Web安全威胁:文件上传漏洞、SQL注入漏洞与WebShell
  • MySQL 8.0 OCP 1Z0-908 题目解析(37)
  • Qt 异步编程模式与应用
  • LeetCode——1717. 删除子字符串的最大得分
  • JVM参数
  • 7月26日京东秋招第一场第二题
  • sssss
  • python面向对象编程详解
  • 机器学习的工作流程
  • JVM-GC 相关知识
  • 配置DNS正反向解析
  • 深度学习(鱼书)day03--神经网络(后两节)
  • 【教程】无需迁移IDE!Augment原生插件实现Cursor无缝平替 Claude-4无限用
  • ClickHouse高性能实时分析数据库-消费实时数据流(消费kafka)
  • Flutter开发实战之路由与导航
  • Redis面试精讲 Day 5:Redis内存管理与过期策略
  • HTTP 协议的基本格式和 fiddler 的用法
  • 15.6 DeepSpeed+Transformers实战:LLaMA-7B训练效率提升210%,显存直降73%
  • Spring Boot 项目启动自动执行逻辑的最佳实践:掌握 CommandLineRunner
  • Windows11下和Vmware中的Ubuntu22.04设置samba服务遇到的一个问题- valid users和guest设置冲突
  • 【架构师从入门到进阶】第五章:DNSCDN网关优化思路——第十节:网关安全-单向加密
  • k8s之控制器详解
  • 什么是Paimon?Paimon是什么?
  • 兼容性问题记录
  • 速通python加密之RSA加密
  • 刷题日记0726
  • AI使能的SVD算子:基于深度学习的矩阵分解方法
  • 个人电脑配置IPv6的详细步骤
  • 【线段树】P8473 [Aya Round 1 H] 破碎的历史|普及+