精灵王's Blog


  • 首页

  • 文章归档

  • 所有分类

  • 关于我

  • 搜索
异步编程 技术方案设计 集合 设计模式 三亚 游玩 转载 Linux 观察者模式 事件 Spring SpringCloud 实战 实战,SpringCloud 源码分析 线程池 同步 锁 线程 线程模型 动态代理 字节码 类加载 垃圾收集器 垃圾回收算法 对象创建 虚拟机内存 内存结构 Java

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

发表于 2020-09-18 | 分类于 Java虚拟机 | 0 | 阅读次数 114

标记 — 清除算法(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 许可协议。转载请注明出处!
# 异步编程 # 技术方案设计 # 集合 # 设计模式 # 三亚 # 游玩 # 转载 # Linux # 观察者模式 # 事件 # Spring # SpringCloud # 实战 # 实战,SpringCloud # 源码分析 # 线程池 # 同步 # 锁 # 线程 # 线程模型 # 动态代理 # 字节码 # 类加载 # 垃圾收集器 # 垃圾回收算法 # 对象创建 # 虚拟机内存 # 内存结构 # Java
java 同步锁:synchronized 关键字
自己写一个简单的线程池
  • 文章目录
  • 站点概览
精 灵 王

精 灵 王

青春岁月,以此为伴

48 日志
10 分类
29 标签
RSS
E-mail
Creative Commons
Links
  • 添加友链请联系邮箱
© 2021 精 灵 王
渝ICP备2020013371号
0%