精灵王


  • 首页

  • 文章归档

  • 所有分类

  • 关于我

  • 搜索
设计模式-行为型 设计模式-创建型 设计模式-结构型 设计 系统设计 设计模式之美 分布式 Redis 并发编程 个人成长 周志明的软件架构课 架构 单元测试 LeetCode 工具 位运算 读书笔记 操作系统 MySQL 异步编程 技术方案设计 集合 设计模式 三亚 游玩 转载 Linux 观察者模式 事件 Spring SpringCloud 实战 实战,SpringCloud 源码分析 线程池 同步 锁 线程 线程模型 动态代理 字节码 类加载 垃圾收集器 垃圾回收算法 对象创建 虚拟机内存 内存结构 Java

Java 虚拟机垃圾回收算法总结

发表于 2020-09-18 | 分类于 Java虚拟机 | 0

标记 — 清除算法(Mark Sweep)

最基本的垃圾收集算法,从它的名字就可以看得出来,算法分为“标记”和“清除”两个阶段:首先标记处所有需要回收的对象,在标记完成后统一回收被标记的对象。

标记清除算法主要不足有两个方面:

  1. 效率低

    标记和清除两个阶段的效率都不够高

  2. 空间碎片问题

    标记清除之后会产生大量不连续的内存碎片,如果空间碎片太多,会导致以后程序需要分配打对象时无法找到足够的内存空间,而不得不触发一次垃圾回收的动作

复制算法(Copying)

为了解决标记清除的效率问题,它将内存分为大小相等的两个区域,但是每次只使用其中一块区域。当其中一块区域用完了,就将还活着的对象复制(移动堆顶指针,按顺序分配内存)到另外一块区域上,然后再把已使用的那一块区域空间一次清理掉。

优点:

实现简单,运行高效,不会产生空间碎片问题

缺点:

浪费内存,将内存缩小为了原来的一般。

在对象存活率高的时候效率会变得低下。

虚拟机一般都才用此方法来回收新生代。虚拟机将内存划分成为一块较大的Eden区和两块较小的Survivor区,每次就使用Eden区和一块Survivor区,当回收时,将Eden区和Survivor区还存活的对象一次性复制到另一块Survivor区,最后清理掉Eden区和用过的Survivor区。Hotspot 默认Eden和一个Survivor区的大小比例是8:1,也就是每次新生代的可用内存为整个新生代的90%,也就浪费了10%,这完成是可以接受的。当Survivor区内存不够时,需要依赖老年代区域来进行分担内存分配。

标记——整理算法(Mark Compact)

复制收集算法在对象存活率高的时候效率会变得低下。标记过程和“标记——清除”算法一样,区别是后续步骤不再是直接对对象进行清理,而是让所有存活对象都向一端移动,然后直接清理掉边界以外的内存。
untitled

分代收集算法

在新生代,每次垃圾回收都有大批量的对象死去,只有少量对象存活,就选用复制算法,这样只需要付出少量存活对象的复制成本就可以完成垃圾收集工作。

而老年代中因为对象的存活率高、且没有额外的空间来分担,就必须使用“标记——清除”或者“标记——整理”算法来进行回收。

精 灵 王 wechat
👆🏼欢迎扫码关注微信公众号👆🏼
  • 本文作者: 精 灵 王
  • 本文链接: https://jinglingwang.cn/archives/gc-algorithm
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# 设计模式-行为型 # 设计模式-创建型 # 设计模式-结构型 # 设计 # 系统设计 # 设计模式之美 # 分布式 # Redis # 并发编程 # 个人成长 # 周志明的软件架构课 # 架构 # 单元测试 # LeetCode # 工具 # 位运算 # 读书笔记 # 操作系统 # MySQL # 异步编程 # 技术方案设计 # 集合 # 设计模式 # 三亚 # 游玩 # 转载 # Linux # 观察者模式 # 事件 # Spring # SpringCloud # 实战 # 实战,SpringCloud # 源码分析 # 线程池 # 同步 # 锁 # 线程 # 线程模型 # 动态代理 # 字节码 # 类加载 # 垃圾收集器 # 垃圾回收算法 # 对象创建 # 虚拟机内存 # 内存结构 # Java
java 同步锁:synchronized 关键字
自己写一个简单的线程池
  • 文章目录
  • 站点概览
精 灵 王

精 灵 王

青春岁月,以此为伴

106 日志
14 分类
48 标签
RSS
Github E-mail
Creative Commons
Links
  • 添加友链说明
© 2023 精 灵 王
渝ICP备2020013371号
0%