Java 中有哪些垃圾回收算法?
Java 中的垃圾回收算法
Java 中的垃圾回收(Garbage Collection,GC)机制通过多种算法实现对堆内存的管理。以下是常见的垃圾回收算法:
1. 标记-清除算法(Mark-Sweep)
工作原理
- 标记阶段:遍历对象图,标记所有可达对象。
- 清除阶段:清除未标记的不可达对象,回收内存。
特点
- 简单直接,适用于基本场景。
- 缺点:
- 清除后会产生大量内存碎片。
- 标记和清除过程需要暂停应用线程(STW,Stop-The-World)。
示例
初始内存: [A][B][C][空][空]
标记阶段: [A*][B*][C*][空][空] (*表示可达)
清除阶段: [A][B][C][空][空]
2. 复制算法(Copying)
工作原理
- 将内存分为两块,每次只使用其中一块。
- 当一块内存满了时,将可达对象复制到另一块内存,并清空原来的内存。
特点
- 优点:
- 简单高效,不会产生内存碎片。
- 缺点:
- 可用内存减少为原来的一半。
使用场景
- 常用于新生代垃圾回收(Minor GC)。
示例
初始内存: [A][B][C][空][空]
复制阶段: [空][空][空][A][B][C]
3. 标记-整理算法(Mark-Compact)
工作原理
- 标记阶段:标记所有可达对象。
- 整理阶段:将存活对象移动到内存的一端,清理掉其他空间。
特点
- 优点:
- 不会产生内存碎片。
- 缺点:
- 移动对象的过程会影响性能。
使用场景
- 常用于老年代垃圾回收(Major GC 或 Full GC)。
示例
初始内存: [A][B][C][空][空]
标记阶段: [A*][B*][C*][空][空]
整理阶段: [A][B][C][空][空]
4. 分代回收算法(Generational Collection)
工作原理
- 将堆内存划分为多个区域:
- 新生代:存放短生命周期的对象。
- 老年代:存放长生命周期的对象。
- 永久代(JDK 7 及以前)/元空间(JDK 8 及以后):存放类元信息。
特点
- 不同代使用不同的回收算法:
- 新生代:采用复制算法。
- 老年代:采用标记-清除或标记-整理算法。
- 优点:
- 针对对象生命周期的特点进行优化,提高效率。
使用场景
- 是当前 Java 垃圾回收的核心机制,大多数垃圾收集器都基于此设计。
5. 分区算法(Region-Based Collection)
工作原理
- 将堆内存划分为多个相等的区域(Region)。
- 每个区域可以动态作为新生代或老年代的一部分。
- 优先回收垃圾最多的区域,减少整体回收时间。
特点
- 优点:
- 更加灵活,能避免全堆扫描。
- 提高内存管理效率。
- 缺点:
- 实现较复杂,调优成本较高。
使用场景
- G1 垃圾收集器是分区算法的典型应用。
假设堆内存分为多个区域:
[Region1][Region2][Region3][Region4][Region5]
垃圾最多的区域先被回收,例如优先回收 Region3。
6. 总结
| 算法类型 | 工作原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 标记-清除 | 标记可达对象,清除不可达对象 | 简单直接 | 会产生内存碎片,STW 明显 | 老年代或简单场景 |
| 复制 | 对象复制到另一块内存 | 高效,无碎片 | 内存利用率低 | 新生代 |
| 标记-整理 | 移动存活对象并清理无用对象 | 无碎片 | 移动对象耗时 | 老年代 |
| 分代回收 | 根据对象生命周期分代回收 | 效率高 | 实现复杂 | 新生代和老年代结合 |
| 分区算法 | 将堆分为多个区域,优先回收垃圾最多的区域 | 灵活高效 | 实现复杂 | G1 垃圾收集器等 |
结论
- 垃圾回收算法根据应用需求和对象特点选择合适的策略。
- 现代 JVM 通常结合多种算法(如分代回收)以优化性能。
Java 中有哪些垃圾回收算法?的更多相关文章
- 深入理解java虚拟机【垃圾回收算法】
Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...
- Java虚拟机之垃圾回收算法思想总结
1.引用计数法 这是个比较古老而经典的垃圾回收算法,其核心就是在对象被其他所引用的时候计数器加1,而当引用失去时减1.这个方法有非常严重的问题:无法此话有理循环引用的情况,还有就是每次进行加减操作比较 ...
- Java中的垃圾回收算法详解
一.前言 前段时间大致看了一下<深入理解Java虚拟机>这本书,对相关的基础知识有了一定的了解,准备写一写JVM的系列博客,这是第二篇.这篇博客就来谈一谈JVM中使用到的垃圾回收算法. ...
- java中的垃圾回收算法与垃圾回收器
常用的垃圾回收算法 标记-清除 标记清除算法是一种非移动式的回收算法,分为标记 清除 2个阶段,简而言之就是先标记出需要回收的对象,标记完成后再回收掉所有标记的内存对象,如下图 可见回收后图中被标记的 ...
- java虚拟机之垃圾回收算法
标记-清除算法: 这是最基础的,就是之前所讲的两次标记,首先标记出所有 需要回收的对象,然后进行统一清除, 这有两缺点:一是效率低,标记和清除(开启低优先级进行回收)都是低效率的.第二是空间问题,标记 ...
- java面试一日一题:java中垃圾回收算法有哪些
问题:请讲下在java中有哪些垃圾回收算法 分析:该问题主要考察对java中垃圾回收的算法以及使用场景 回答要点: 主要从以下几点去考虑, 1.GC回收算法有哪些 2.每种算法的使用场景 3.基于垃圾 ...
- 每日一问:讲讲 Java 虚拟机的垃圾回收
昨天我们用比较精简的文字讲了 Java 虚拟机结构,没看过的可以直接从这里查看: 每日一问:你了解 Java 虚拟机结构么? 今天我们必须来看看 Java 虚拟机的垃圾回收算法是怎样的.不过在开始之前 ...
- Java GC 垃圾回收算法 内存分配
垃圾回收(Garbage Collection, GC)是Java不同于c与c++的重要特性之一. 他帮助Java自动清空堆中不再使用的对象. 由于不需要手动释放内存,程序员在编程中也可以减少犯错的机 ...
- JAVA虚拟机垃圾回收算法原理
除了释放不再被引用的对象外,垃圾收集器还要处理堆碎块.新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活动的对象之间.请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的总空 ...
- (转)《深入理解java虚拟机》学习笔记3——垃圾回收算法
Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...
随机推荐
- linux命令操作android手机
目的 通过一台linux机器操作android手机做一些常用的操作 复杂的操作都是由简单操作开始的, 可以自行发掘 环境 笔记本: thinkpad t480 操作系统: archlinux adb版 ...
- 小程序之navigator跳转方式
navigator中的open-type可以决定小程序的跳转方式: 是否关闭当前页面 或者说以何种方式进行跳转 标签<navigator>中 open-type属性表示小程序的跳转方式: ...
- AI编程:Coze + Cursor实现一个思维导图的浏览器插件
这是小卷对AI编程工具学习的第3篇文章,今天以实际开发一个思维导图的需求为例,了解AI编程开发的整个过程 1.效果展示 2.AI编程开发流程 虽然AI编程知识简单对话就行,不过咱要逐步深入到项目开发中 ...
- 使用yarn安装依赖包出现“There appears to be trouble with your network connection. Retrying...”超时的提醒
我们在使用yarn安装依赖包文件的时候,可能会出现"There appears to be trouble with your network connection. Retrying... ...
- Linux下普通用户免密切换root
问题需求: Linux下普通用户doge免密切换root 问题解决: Linux下普通用户切换到root用户下,默认情况是需要输入密码很不方便,因此需要实现普通用户doge免密切换到root用户. 示 ...
- Centos 7 安装Redis5 详细步骤 备忘录笔记
通过wget下载tar包 wget http://download.redis.io/releases/redis-5.0.5.tar.gz 解压包 tar -zxvf redis-5.0.5.tar ...
- OSAL架构
OSAL操作系统最多可以支持16个任务,由任务功耗管理PwrMgr_task_state变量可知,而OSAL每个任务最多只能支持16个事件处理,理论上最大可以执行256个事件处理. 对于一些运算能力不 ...
- Qt 枚举类型 值、字符串、枚举类型互转
枚举类型 class Enum : public QObject{ Q_OBJECT public: enum Fruit{ APPLE = 0, BANANA, POTATO } Q_ENUM(Fr ...
- docker - [07] 部署ES+Kibana
思考问题:以后在Tomcat部署项目,如果每次都要进入容器会十分麻烦,是否可以在容器外部提供一个映射路径,webapps,在外部放置项目,自动同步到容器内部? 一.启动es docker run -d ...
- idea中启动web、jsp项目
1. idea打开项目 选择要打开的项目的根目录 2. 项目配置 配置jdk modules配置 添加web 添加依赖 删除爆红的依赖 添加依赖目录或者jar 配置web.xml 配置lib 如果没有 ...