文章目录

  • 一、前言
  • 二、判定哪些对象需要被GC
    • 引用计数法Reference Count
    • 可达性算法(引用链法Tracing)
  • 三、GC算法
    • 标记—清除
    • 标记—压缩
    • 复制算法
  • 总结
    • 分代收集
    • 补充:HotSpot为什么要分为新生代和老年代?
    • 参考

一、前言

垃圾收集(Garbage Collection ),简称GC。是Java 的一种垃圾自动回收机制,但程序员可以手动执行 System.gc(),通知 GC 运行,但是 Java 语言规范并不保证 GC 一定会执行。

判定哪些对象需要被GC,主要有两种方法,引用计数法和可达性算法。

GC算法包括引用计数法、标记—清除、标记—压缩、复制算法。

二、判定哪些对象需要被GC

引用计数法Reference Count

引用计数法,也叫直接垃圾回收法,是老牌垃圾回收算法,当GC触发时,通过对象的引用来计算要不要回收。

给每个对象分配一个引用计数器,只要该对象被应用,计数器+1.取消引用就-1。

当GC触发时,如果该对象的引用计数器为零,那这个对象就是垃圾。


优点

即时回收,因为对象知道自己什么时候没用

缺点

引用和去除引用伴随着加法减法,影响性能。还有就是很难处理循环引用

需要注意的是,在主流虚拟机中,并未涉及引用计数法。

可达性算法(引用链法Tracing)

可达性算法,也叫间接垃圾回收算法。

该算法的思想是:从一个被称为 GC Roots 的对象开始向下搜索,找到活着的对象,活着得对象可以链接到,而如果一个对象到 GC Roots 没有任何引用链相连时,则说明此对象不可用。

Tracing法分为两部分:GC root和GC heap

那么GC root有哪些呢?

  1. java虚拟机栈中的引用的对象
  2. 方法区中的类静态属性引用的对象
  3. 方法区中的常量引用的对象,例如final User u = new User();
  4. 本地方法栈中的JNI(native方法)引用的对象

这些GC root会与GC heap中的对象进行相连。

三、GC算法

标记—清除

标记—清除算法是现代垃圾回收算法的思想基础

这个算法将垃圾回收分为了两个阶段,标记阶段和清除阶段

1.在标记阶段,首先通过根节点,标记所有从根节点开始可达对象,这时的可达对象代表还“有用”,而未标记的对象就是未被引用的垃圾对象。

2.在清除阶段,清除未被标记的垃圾对象。

优点

实现起来简单,不需要额外的空间

缺点

逐渐产生被细化的分块,不久后就会导致无数的 小分块散布在堆的各处,并且在分配对象的时候还得先遍历那些内存块可以用。

标记—压缩

标记-压缩算法适合用于存活对象较多的场合,如老年代

它在标记-清除算法的基础上做了一些优化,即在标记—清除算法后,将所有存活的对象压缩到内存的一端,然后清理这个边界外的所有空间

缺点:清除算法中,清除阶段也要搜索整个堆,不过搜索 1 次就够了。但 GC 标记 - 压缩算法要搜索 3 次,这样就要花费约 3 倍的时间,这是一个相当巨大的缺陷,特别是堆越大,所消耗的成本也就越大(看图)

优点:堆利用效率高。
而且 GC 标记 - 压缩算法不会出现 GC 复制算法那样只能利用半个堆的情况

复制算法

复制算法,在标记清除的的基础上改进而来的,适用于对象存活度低的场景,如年轻代


堆空间分配中,新生代:老年代 = 1:2

思想是将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。
需要注意的是,在复制算法下,两个survivor区(From和To区)同⼀时间会有⼀个满⼀个空,是交替的,并且空的总是To区。

值得知道的是,如果一次Young GC后存活的对象过多不能进入Survivor区,那么就直接进入老年代。

优点:
1、优秀的吞吐量: GC 标记 - 清除算法消耗的吞吐量是搜索活动对象(标记阶段)所花费的时间和搜索整体 堆(清除阶段)所花费的时间之和。
另一方面,因为 GC 复制算法只搜索并复制活动对象,所以跟一般的 GC 标记 - 清除算 法相比,它能在较短时间内完成 GC。也就是说,其吞吐量优秀。

2、高速分配:GC 复制算法不使用空闲链表。这是因为分块是一个连续的内存空间。比起 GC 标记 - 清除算法和引用计数法等使用空闲链表的分配,GC 复制算法明显快得多。

3、不会发生碎片化

缺点:
浪费内存空间,因为用这种算法,必须保证To区是空的。假如极端情况下对象100%存在,内存空间就会不够。所以在对象存存活度低时适合使用,我们知道年轻代是存活度低,所以事实上就是使用的复制算法。

总结


没有最好的算法,但有最合适的算法。

分代收集

现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生代和老年代。

在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担保,一般采用标记整理算法。

补充:HotSpot为什么要分为新生代和老年代?

  • 因为有的对象寿命长,有的对象寿命短。应该将寿命长的对象放在一个区,寿命短的对象放在一个区。
  • 不同的区采用不同的垃圾收集算法。寿命短的区清理频次高一点,寿命长的区清理频次低一点。提高效率。

参考

B栈狂神说JVM入门
JVM GC算法

JVM 知识梳理 (二) GC算法相关推荐

  1. 性能优化专题 - JVM 性能优化 - 04 - GC算法与调优

    目录导航 前言 Garbage Collect(垃圾回收) 如何确定一个对象是垃圾? 引用计数法 可达性分析 垃圾收集算法 标记-清除(Mark-Sweep) 复制(Copying) 标记-整理(Ma ...

  2. JVM读书笔记之GC算法

    前面我们说了如何判断对象的生存与死亡,JVM判断了对象的生存与死亡之后需要一定的策略区回收死亡对象.本篇博客对四种常用的GC算法的思想进行一些说明. 标记--清除算法: 最基础的算法,分为标记和清除两 ...

  3. 【JVM】四种GC算法(分代收集+三种标记算法)

    目录 参考文章 四种GC算法 分代收集算法(理论) 标记清除算法 标记整理算法 标记复制算法 三种算法的优缺点 参考文章 JVM的4种垃圾回收算法.垃圾回收机制与总结_我是guyue,guyue就是我 ...

  4. JVM的四种GC算法

    介绍 程序在运行过程中,会产生大量的内存垃圾(一些没有引用指向的内存对象都属于内存垃圾,因为这些对象已经无法访问,程序用不了它们了,对程序而言它们已经死亡),为了确保程序运行时的性能,java虚拟机在 ...

  5. JVM常见4种GC算法

    JVM常见GC算法 1.标记-清除算法(Mark-Sweep) 2.标记-整理(压缩)算法(Mark-Compact) 3.复制算法(Copying) 4.分代收集(Generational Coll ...

  6. JVM知识梳理(二)之垃圾收集器与内存分配策略

    目录 一.如何判断一个对象已死? 1.引用计数器算法 2.可达性分析 一次对象自我拯救的演示 二.垃圾收集算法 1. 分代收集理论 2. 标记-清除算法 3. 标记-复制算法 4. 标记-整理算法 三 ...

  7. JVM知识梳理,java分层架构

    首先,回收前我们必须确定那些对象可以回收.哪些不能回收,哪些暂时不能回收!这就用到判断对象是否存活的算法 引用计数法( Reference Counting):这个方法JAVA现在不使用, 原理:在每 ...

  8. (六)JVM成神路之GC基础篇:对象存活判定算法、GC算法、STW、GC种类详解

    引言 经过前面五个章节的分析后,对于JVM的大部分子系统都已阐述完毕,在本文中则开始对JVM的GC子系统进行全面阐述,GC机制也是JVM的重中之重,调优.监控.面试都逃不开的JVM话题. 在前面分析J ...

  9. 阿里大牛精心整理了46张PPT,教你弄懂JVM、GC算法和性能调优!

    2019独角兽企业重金招聘Python工程师标准>>> 本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述. 好 ...

最新文章

  1. vscode配置记录
  2. Formik官方应用案例解析( 五)React Native
  3. 思科查看服务器启动配置文件,启动配置检查UCS
  4. 读书笔记—《销售铁军》随记7
  5. dj电商-模型类设计-1.x-订单模块表
  6. no value specified for java.sql.date,求助No value specified for parameter 2
  7. 【转】CentOs中Apache开启rewrite模块详解
  8. mysql的dockerfile_dockerfile构建mysql镜像
  9. elfutils库交叉编译
  10. linux程序设计第四版中文pdf下载地址
  11. java 工作流框架都有哪些_java工作流框架有哪些?哪个比较好?
  12. 做网站搭建服务器,个人服务器搭建做网站
  13. RTX自动配置客户端服务器地址
  14. JQuery和javascript优秀插件收集
  15. pytorch分布式训练 DistributedSampler、DistributedDataParallel
  16. java noi和io
  17. 圣诞要到了~教你用Python制作一个表白神器——照片墙,祝你成功
  18. Java中的空指针异常
  19. 代码关联Git远程仓库笔记
  20. configure: error: no acceptable C compiler found in $PATH 问题解决

热门文章

  1. 在 JavaScript 比较中应该使用哪个等号运算符(== vs ===)?
  2. js中数组排序的五种方式
  3. 设置 EXTRA_CFLAGS 以编译 debug 版本 dpdk 库
  4. JS 颜色16进制转rgb,rbg转16进制
  5. 红外热成像在冠状病毒筛查中的应用
  6. 计算机ppt基础知识题库,计算机一级考试试题题库office(2)
  7. 最好的Android apps,Android apps推荐下载
  8. 气液增压缸选型要认真对待
  9. linux socket 混杂模式,设置混杂模式的例子
  10. 虚拟主机的安全吗?如何选择安全的虚拟主机?