• Java基础-JVM:垃圾回收算法与垃圾收集器



    在这里插入图片描述

    垃圾回收算法和垃圾收集器算是JVM的基础,也是Java的核心知识,Java程序员们都应该了解,并根据实际需要进行垃圾收集器的选择和JVM参数调优。

    垃圾回收算法

    • 常用的有三种垃圾回收算法,一些新版本jdk的算法暂时不在这里介绍。
    • 新生代对象多又小,需要频繁迁移整理(而不是删除),一般采用复制算法
    • 老年代对象大且变动不频繁,一般变动就清理,一般采用“标记-清除”算法或“标记-压缩”算法

    标记-清除算法

    • mark sweep,简称 MS
    • 缺点是容易造成碎片化
    • “标记-清除”(Mark-Sweep)算法,如它的名字一样,算法分为“标记”和“清除”两个阶段
    • 首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。

    复制算法

    • copying
    • 缺点是浪费空间
    • “复制”(Copying)的收集算法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。
    • 当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

    标记-压缩算法

    • mark compare,简称 MC
    • 标记-压缩算法,也称标记-整理算法
    • 标记过程仍然与“标记-清除”算法一样
    • 但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存

    垃圾收集器

    新生代收集器:Serial、 ParNew 、 Parallel Scavenge

    老年代收集器: CMS 、Serial Old、Parallel Old

    整堆收集器: G1 , ZGC (不涉年代)。

    从串行-并行,从几十M,到几个G,到几十G

    Serils / Serils Old

    • 单线程垃圾收集器
    • Serial收集器(复制算法): 新生代单线程收集器,标记和清理都是单线程,优点是简单高效;
    • Serial Old收集器 (标记-整理算法): 老年代单线程收集器,Serial收集器的老年代版本;

    ParNew

    • ParNew收集器 (复制算法): 新生代收并行集器
    • 实际上是Serial收集器的多线程版本
    • 在多核 CPU环境下有着比Serial更好的表现;

    Parallel Scavenge / Parallel Old

    • 多线程并行垃圾收集器
    • JDK1.8默认默认垃圾收集器
    • Parallel Scavenge收集器 (复制算法): 新生代并行收集器,追求高吞吐量,高效利用 CPU
    • 吞吐量 = 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高效率的利用CPU时间,尽 快完成程序的运算任务,适合后台应用等对交互相应要求不高的场景
    • Parallel Old收集器 (标记-整理算法): 老年代并行收集器,吞吐量优先,Parallel Scavenge收 集器的老年代版本;

    CMS

    • concurrent mark swep 的缩写,即并发的标记-清除
    • CMS(Concurrent Mark Sweep)收集器,使用标记-清除算法
    • 老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短GC回收停顿时间。
    • 三色标记 - 错标 - Incremental Update - Remark

    G1

    • JDK1.9默认垃圾收集器
    • G1(Garbage First)收集器 ,使用标记-整理算法,是Java堆并行收集器
    • G1收集器是JDK1.7提供的一 个新收集器,G1收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片。
    • 此外,G1回收集器不同于之前的收集器的一个重要特点是:G1回收的范围是整个Java堆(包括新生代,老年代),而前六种收集器回收的范围仅限于新生代或老年代。
    • 1.9后默认的垃圾回收算法,特点保持高回收率的同时减少停顿。采用每次只清理一部分,而不是清理全部的增量式清理,以保证停顿时间不会过长。
    • 其取消了年轻代与老年代的物理划分,但仍属于分代收集器,算法将堆分为若干个逻辑区域(region),一 部分用作年轻代,一部分用作老年代,还有用来存储巨型对象的分区.
    • 同CMS相同,会遍历所有对象,标记引用情况,清除对象后会对区域进行复制移动,以整合碎片空间
    • 年轻代回收: 并行复制采用复制算法,并行收集,会StopTheWorld
    • 老年代回收: 会对年轻代一并回收
    • 标记-清除过程
      • 初始标记 完成堆root对象的标记,会StopTheWorld.
      • 并发标记 GC线程和应用线程并发执行.
      • 最终标记 完成三色标记周期,会StopTheWorld.
      • 复制/清除 会优先对可回收空间加大的区域进行回收

    ZGC

    • Open JDK 11加入
    • ZGC (Z Garbage Collector)是一款由Oracle公司研发的,以低延迟为首要目标的一款垃圾收集器
    • 它是基于动态Region内存布局,(暂时)不设年龄分代,使用了读屏障、染色指针和内存多重映射等技术来实现可并发的标记-整理算法的收集器。
    • 在 JDK 11 新加入,还在实验阶段,主要特点是:回收TB级内存(最大4T),停顿时间不超过10ms。
    • 优点:低停顿,高吞吐量, ZGC 收集过程中额外耗费的内存小。
    • 缺点:浮动垃圾

    垃圾收集器选择

    • 我们平常的 Web 服务器,都是对响应性要求非常高的。选择性其实就集 中在 CMS 、 G1 、 ZGC 上。而对于某些定时任务,使用并行收集器,是一个比较好的选择。下面详细讲一下,仅供参考。
    • 如果你的堆大小不是很大(比如 100MB ),选择串行收集器一般是效率最高的。
      参数: -XX:+UseSerialGC 。
    • 如果你的应用运行在单核的机器上,或者你的虚拟机核数只有单核,选择串行收集器依然是合适的,这时候启用一些并行收集器没有任何收益。
      参数: -XX:+UseSerialGC 。
    • 如果你的应用是“吞吐量”优先的,并且对较长时间的停顿没有什么特别的要求。选择并行收集 器是比较好的。
      参数: -XX:+UseParallelGC 。
    • 如果你的应用对响应时间要求较高,想要较少的停顿。甚至 1 秒的停顿都会引起大量的请求失败,那么选择 G1 、 ZGC 、 CMS 都是合理的。虽然这些收集器的 GC 停顿通常都比较短,但它需要一些额外的资源去处理这些工作,通常吞吐量会低一些。
      参数: -XX:+UseConcMarkSweepGC 、 -XX:+UseG1GC 、 -XX:+UseZGC 等。
  • 相关阅读:
    51单片机实现换能器超声波测水深
    学校网页设计成品 基于HTML+CSS+JavaScript仿山东财经大学官网 学校班级网页制作模板 校园网页设计成品
    2023年十大最佳 iPhone 恢复软件
    [LeetCode/力扣][Java] 0315. 计算右侧小于当前元素的个数(Count of Smaller Numbers After Self)
    Tomcat
    漏洞复现----41、Spring Data Rest 远程命令执行漏洞(CVE-2017-8046)
    SpringBoot初级开发--服务请求(GET/POST)所有参数的记录管理(8)
    电容笔和Apple pencil区别有哪些区别?苹果笔替代笔推荐
    ctfhub ssrf(3关)
    【产品人卫朋】华为IPD流程体系:集成产品开发框架
  • 原文地址:https://blog.csdn.net/u010882234/article/details/126025344