侧边栏壁纸
博主头像
DJ's Blog博主等级

行动起来,活在当下

  • 累计撰写 133 篇文章
  • 累计创建 51 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

【JVM】垃圾回收

Administrator
2022-04-04 / 0 评论 / 0 点赞 / 63 阅读 / 5486 字

【JVM】垃圾回收

垃圾确定

引用计数法

  • 概念:对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾,如果一个对象没有任何指针对其引用,它就是垃圾。
  • 缺点:如果AB相互持有引用,导致永远不能被回收。

可达性分析

  • 概念:通过GC Root对象,开始向下寻找,看某个对象是否可达。
  • 能作为GC Root的对象:类加载器、Thread、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量等。

垃圾收集算法

标记-清除(Mark-Sweep)

标记

  • 找出内存中需要回收的对象,并且把它们标记出来,
  • 堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时

清除

  • 清除掉被标记需要回收的对象,释放出对应的内存空间

缺点

  • 标记清除之后会产生大量不连续的内存碎片,导致因无法找到足够的连续内存分配大对象从而触发GC。
  • 标记和清除两个过程都比较耗时,效率不高。

复制(Copying)

流程

  • 将内存划分为两块相等的区域,每次只使用其中一块,如下图所示:
  • 当其中一块内存使用完了,就将还存活的对象复制到另外一块上面,然后把已经使用过的内存空间一次清除掉。

缺点

  • 空间利用率降低。

标记-整理(Mark-Compact)

流程

  • 标记过程仍然与"标记-清除"算法一样,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

分代收集算法

  • Young区:复制算法(对象在被分配之后,可能生命周期比较短,Young区复制效率比较高)
  • Old区:标记清除或标记整理(Old区对象存活时间比较长,复制来复制去没必要,不如做个标记再清理)

垃圾收集器

吞吐量和停顿时间

  • 吞吐量:运行用户代码时间 / 运行用户代码时间 + 垃圾收集时间。
  • 停顿时间:垃圾收集器进行垃圾回收终端应用执行响应的时间。
  • 停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验。
  • 高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任
    务。
  • 这两个指标也是评价垃圾回收器好处的标准,其实调优也就是在观察者两个变量。

Serial收集器

Serial Old收集器

ParNew收集器

Parallel Old收集器

Parallel Scavenge收集器

CMS收集器

目标

  • 获取最短回收停顿时间

算法

  • 标记-清除

特性

  • 老年代的垃圾收集器
  • 并发收集、低停顿
  • 非常符合互联网站或者B/S系统的服务端上,重视服务的响应速度,希望系统停顿时间最短的应用。
  • 内存回收过程与用户线程一起并发地执行
  • 对CPU资源非常敏感
  • 产生大量空间碎片、并发阶段会降低吞吐量

流程

  • 初始标记(initial mark):标记GC Roots能关联到的对象,速度很快,但是需要暂停用户线程(Stop The World)
  • 并发标记(concurrent mark):进行GC Roots Tracing,可以和用户线程并发执行
  • 重新标记(remark):修改并发标记因用户程序变动的内容,需要STW
  • 并发清除(concurrent sweep):可以和用户线程并发执行

G1收集器

算法

  • 标记-整理

特性

  • 并行与并发:充分利用多CPU、多核环境下的硬件优势。
  • 分代收集:不需要其他收集器配合就能独立管理整个GC堆
  • 空间整合:不会导致空间碎片
  • 可预测的停顿:能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒
  • 整个Java堆划分为多个大小相等的独立区域(Region)
  • JDK 7开始使用,JDK 8非常成熟,JDK 9默认的垃圾收集器,适用于新老生代

流程

  • 初始标记(Initial Marking):标记一下GC Roots能够关联的对象,并且修改TAMS的值,耗时很短,需要STW
  • 并发标记(Concurrent Marking):从GC Roots进行可达性分析,找出存活的对象,耗时较长,可以与用户线程并发执行
  • 最终标记(Final Marking):修正在并发标记阶段因为用户程序的并发执行导致变动的数据,需要STW
  • 筛选回收(Live Data Counting and Evacuation):对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间制定回收计划

垃圾收集器比较

如何选择合适的垃圾收集器

官网参考:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthref28

  • 优先调整堆的大小让服务器自己来选择
  • 如果内存小于100M,使用串行收集器
  • 如果是单核,并且没有停顿时间要求,使用串行或JVM自己选
  • 如果允许停顿时间超过1秒,选择并行或JVM自己选
  • 如果响应时间最重要,并且不能超过1秒,使用并发收集器

如何开启需要的垃圾收集器

  • -XX:+UseConcMarkSweepGC:使用CMS垃圾收集器
  • -XX:+UseG1GC:使用G1垃圾收集器
0
jvm

评论区