「译文」Java 垃圾收集参考手册(三):GC 算法基础篇

简介: 「译文」Java 垃圾收集参考手册(三):GC 算法基础篇

相关术语翻译说明:

Mark, 标记;

Sweep, 清除;

Compact, 整理; 也有人翻译为压缩, 译者认为 GC 时不存在压缩这回事。

Copy, 复制; copy 用作名词时一般翻译为拷贝 / 副本, 用作动词时翻译为复制。

注: 《垃圾回收算法手册 》将 Mark and Sweep 翻译为: 标记 - 清扫 算法; 译者认为 标记 - 清除 更容易理解。

GC 算法基础

您应该已经阅读了前面的章节。

本章简要介绍 GC 的基本原理和相关技术, 下一章节 再详细讲解 GC 算法的具体实现。各种垃圾收集器的实现细节虽然并不相同, 但总体而言, 垃圾收集器都专注于两件事情:

  • 查找所有存活对象
  • 抛弃其他的部分, 即死对象, 不再使用的对象。

第一步, 记录 (census) 所有的存活对象, 在垃圾收集中有一个叫做 标记(Marking) 的过程专门干这件事。

标记可达对象(Marking Reachable Objects)

现代 JVM 中所有的 GC 算法, 第一步都是找出所有存活的对象。下面的示意图对此做了最好的诠释:

03_01_Java-GC-mark-and-sweep.png

首先, 有一些特定的对象被指定为 Garbage Collection Roots(GC 根元素)。包括:

  • 当前正在执行的方法里的局部变量和输入参数
  • 活动线程(Active threads)
  • 内存中所有类的静态字段(static field)
  • JNI 引用

其次, GC 遍历 (traverses) 内存中整体的对象关系图(object graph), 从 GC 根元素开始扫描, 到直接引用,以及其他对象(通过对象的属性域)。所有 GC 访问到的对象都被 ** 标记(marked)** 为存活对象。

存活对象在上图中用蓝色表示。标记阶段完成后, 所有存活对象都被标记了。而其他对象 (上图中灰色的数据结构) 就是从 GC 根元素不可达的, 也就是说程序不能再使用这些不可达的对象(unreachable object)。这样的对象被认为是垃圾, GC 会在接下来的阶段中清除他们。

在标记阶段有几个需要注意的点:

在标记阶段, 需要暂停所有应用线程, 以遍历所有对象的引用关系。因为不暂停就没法跟踪一直在变化的引用关系图。这种情景叫做 Stop The World pause (全线停顿), 而可以安全地暂停线程的点叫做安全点(safe point), 然后, JVM 就可以专心执行清理工作。安全点可能有多种因素触发, 当前, GC 是触发安全点最常见的原因。

此阶段暂停的时间, 与堆内存大小, 对象的总数没有直接关系, 而是由 存活对象 (alive objects) 的数量来决定。所以增加堆内存的大小并不会直接影响标记阶段占用的时间。

标记 阶段完成后, GC 进行下一步操作, 删除不可达对象。

删除不可达对象(Removing Unused Objects)

各种 GC 算法在删除不可达对象时略有不同, 但总体可分为三类: 清除 (sweeping)、整理(compacting) 和复制 (copying)。 下一章节 将详细讲解这些算法。

Sweep(清除)

Mark and Sweep(标记 - 清除) 算法的概念非常简单: 直接忽略所有的垃圾。也就是说在标记阶段完成后, 所有不可达对象占用的内存空间, 都被认为是空闲的, 因此可以用来分配新对象。

这种算法需要使用 空闲表(free-list), 来记录所有的空闲区域, 以及每个区域的大小。维护空闲表增加了对象分配时的开销。此外还存在另一个弱点 —— 明明还有很多空闲内存, 却可能没有一个区域的大小能够存放需要分配的对象, 从而导致分配失败(在 Java 中就是 OutOfMemoryError)。

03_02_GC-sweep.png

Compact(整理)

标记 - 清除 - 整理算法 (Mark-Sweep-Compact), 将所有被标记的对象(存活对象), 迁移到内存空间的起始处, 消除了标记 - 清除算法的缺点。 相应的缺点就是 GC 暂停时间会增加, 因为需要将所有对象复制到另一个地方, 然后修改指向这些对象的引用。此算法的优势也很明显, 碎片整理之后, 分配新对象就很简单, 只需要通过指针碰撞(pointer bumping) 即可。使用这种算法, 内存空间剩余的容量一直是清楚的, 不会再导致内存碎片问题。

03_03_GC-mark-sweep-compact.png

Copy(复制)

标记 - 复制算法(Mark and Copy) 和 标记 - 整理算法(Mark and Compact) 十分相似: 两者都会移动所有存活的对象。区别在于, 标记 - 复制算法是将内存移动到另外一个空间: 存活区。标记 - 复制方法的优点在于: 标记和复制可以同时进行。缺点则是需要一个额外的内存区间, 来存放所有的存活对象。

03_04_GC-mark-and-copy-in-Java.png

原文链接: GC Algorithms: Basics

翻译人员: 铁锚 http://blog.csdn.net/renfufei

翻译时间: 2016 年 02 月 06 日

GC 算法概述

学习了 GC 算法的相关概念之后, 我们将介绍在 JVM 中这些算法的具体实现。首先要记住的是, 大多数 JVM 都需要使用两种不同的 GC 算法 —— 一种用来清理年轻代, 另一种用来清理老年代。

我们可以选择 JVM 内置的各种算法。如果不通过参数明确指定垃圾收集算法, 则会使用宿主平台的默认实现。本章会详细介绍各种算法的实现原理。

下面是关于 Java 8 中各种组合的垃圾收集器概要列表, 对于之前的 Java 版本来说, 可用组合会有一些不同:

Young Tenured JVM options
Incremental(增量 GC) Incremental -Xincgc
Serial Serial -XX:+UseSerialGC
Parallel Scavenge Serial -XX:+UseParallelGC -XX:-UseParallelOldGC
Parallel New Serial N/A
Serial Parallel Old N/A
Parallel Scavenge Parallel Old -XX:+UseParallelGC -XX:+UseParallelOldGC
Parallel New Parallel Old N/A
Serial CMS -XX:-UseParNewGC -XX:+UseConcMarkSweepGC
Parallel Scavenge CMS N/A
Parallel New CMS -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
G1 -XX:+UseG1GC

看起来有些复杂, 不用担心。主要使用的是上表中黑体字表示的这四种组合。其余的要么是 被废弃(deprecated), 要么是不支持或者是不太适用于生产环境。所以, 接下来我们只介绍下面这些组合及其工作原理:

  • 年轻代和老年代的串行 GC(Serial GC)
  • 年轻代和老年代的并行 GC(Parallel GC)
  • 年轻代的并行 GC(Parallel New) + 老年代的 CMS(Concurrent Mark and Sweep)
  • G1, 负责回收年轻代和老年代
相关文章
|
1月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
1月前
|
存储 缓存 监控
上网行为监控系统剖析:基于 Java LinkedHashMap 算法的时间序列追踪机制探究
数字化办公蓬勃发展的背景下,上网行为监控系统已成为企业维护信息安全、提升工作效能的关键手段。该系统需实时记录并深入分析员工的网络访问行为,如何高效存储和管理这些处于动态变化中的数据,便成为亟待解决的核心问题。Java 语言中的LinkedHashMap数据结构,凭借其独有的有序性特征以及可灵活配置的淘汰策略,为上网行为监控系统提供了一种兼顾性能与功能需求的数据管理方案。本文将对LinkedHashMap在上网行为监控系统中的应用原理、实现路径及其应用价值展开深入探究。
56 3
|
27天前
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
|
2月前
|
存储 机器学习/深度学习 监控
如何监控员工的电脑——基于滑动时间窗口的Java事件聚合算法实现探析​
在企业管理场景中,如何监控员工的电脑操作行为是一个涉及效率与合规性的重要课题。传统方法依赖日志采集或屏幕截图,但数据量庞大且实时性不足。本文提出一种基于滑动时间窗口的事件聚合算法,通过Java语言实现高效、低资源占用的监控逻辑,为如何监控员工的电脑提供一种轻量化解决方案。
63 3
|
4月前
|
存储 算法 Java
解锁“分享文件”高效密码:探秘 Java 二叉搜索树算法
在信息爆炸的时代,文件分享至关重要。二叉搜索树(BST)以其高效的查找性能,为文件分享优化提供了新路径。本文聚焦Java环境下BST的应用,介绍其基础结构、实现示例及进阶优化。BST通过有序节点快速定位文件,结合自平衡树、多线程和权限管理,大幅提升文件分享效率与安全性。代码示例展示了文件插入与查找的基本操作,适用于大规模并发场景,确保分享过程流畅高效。掌握BST算法,助力文件分享创新发展。
|
5月前
|
存储 人工智能 算法
解锁分布式文件分享的 Java 一致性哈希算法密码
在数字化时代,文件分享成为信息传播与协同办公的关键环节。本文深入探讨基于Java的一致性哈希算法,该算法通过引入虚拟节点和环形哈希空间,解决了传统哈希算法在分布式存储中的“哈希雪崩”问题,确保文件分配稳定高效。文章还展示了Java实现代码,并展望了其在未来文件分享技术中的应用前景,如结合AI优化节点布局和区块链增强数据安全。
|
5月前
|
算法 安全 Java
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
182 16
|
21天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于PSO粒子群优化TCN-LSTM时间卷积神经网络时间序列预测算法matlab仿真
本内容展示了一种基于粒子群优化(PSO)与时间卷积神经网络(TCN)的时间序列预测方法。通过 MATLAB2022a 实现,完整程序运行无水印,核心代码附详细中文注释及操作视频。算法利用 PSO 优化 TCN 的超参数(如卷积核大小、层数等),提升非线性时间序列预测性能。TCN 结构包含因果卷积层与残差连接,结合 LSTM 构建混合模型,经多次迭代选择最优超参数,最终实现更准确可靠的预测效果,适用于金融、气象等领域。
|
18天前
|
算法 数据安全/隐私保护
基于Logistic-Map混沌序列的数字信息加解密算法matlab仿真,支持对文字,灰度图,彩色图,语音进行加解密
本项目实现了一种基于Logistic Map混沌序列的数字信息加解密算法,使用MATLAB2022A开发并包含GUI操作界面。支持对文字、灰度图像、彩色图像和语音信号进行加密与解密处理。核心程序通过调整Logistic Map的参数生成伪随机密钥序列,确保加密的安全性。混沌系统的不可预测性和对初值的敏感依赖性是该算法的核心优势。示例展示了彩色图像、灰度图像、语音信号及文字信息的加解密效果,运行结果清晰准确,且完整程序输出无水印。
基于Logistic-Map混沌序列的数字信息加解密算法matlab仿真,支持对文字,灰度图,彩色图,语音进行加解密
|
18天前
|
算法
基于PSO粒子群优化的多无人机路径规划matlab仿真,对比WOA优化算法
本程序基于粒子群优化(PSO)算法实现多无人机路径规划,并与鲸鱼优化算法(WOA)进行对比。使用MATLAB2022A运行,通过四个无人机的仿真,评估两种算法在能耗、复杂度、路径规划效果及收敛曲线等指标上的表现。算法原理源于1995年提出的群体智能优化,模拟鸟群觅食行为,在搜索空间中寻找最优解。环境建模采用栅格或几何法,考虑避障、速度限制等因素,将约束条件融入适应度函数。程序包含初始化粒子群、更新速度与位置、计算适应度值、迭代优化等步骤,最终输出最优路径。

热门文章

最新文章