JVM笔记总结 - 垃圾回收

14. 垃圾回收概述

14.1 什么是垃圾?

垃圾指运行程序中没有任何指针指向的对象。
如果不及时清理,那么这些垃圾就会占用内存直至应用结束,内存迟早会被消耗完

14.4 Java垃圾回收机制

  • 自动内存管理。无序开发人员手动操作内存,避免了内存泄漏的风险,可以专心于业务开发
  • 缺点是会弱化开发者对OOM的解决问题的能力

15. 垃圾回收相关算法

判断对象存活一般有两种方式:引用计数算法可达性分析算法

15.1 垃圾标记阶段 - 引用计数算法

每个对象保存一个引用计数器属性,用于记录对象被引用的情况

  • 优点:实现简单,便于辨识
  • 缺点:计数器增加了时间开销与空间开销
    致命弱点:无法处理循环引用,因此Java回收器里没有使用这类算法

15.2 垃圾标记阶段 - 可达性分析算法

简单,高效,有效解决循环引用的问题,Java选择这种算法

GC Roots为起始点,从上到下搜索被根对象集合所连接的目标对象是否可达,这个链被称为引用链
没有引用链相连的对象即为不可达,可被标记为垃圾对象
在这里插入图片描述

  • 注意:可达性分析算法是STW的重要原因之一

15.3 对象的finalization机制

Java提供了finalization机制允许开发人员对对象销毁之前自定义处理逻辑
垃圾回收此对象之前,总会先调用finalize()方法
finalize()方法允许在子类中被重写

注意:不要主动调用对象的finalize()方法!应该交给GC来调用!

  • finalize()时可能导致对象复活
  • finalize()方法的执行时间没有保证,完全由GC决定。要是不GC很容易卡那
  • 糟糕的finalize()会严重影响GC性能

15.4 GC dump

GC dump是Java虚拟机在进行垃圾回收时生成的一份内存快照文件,用于分析程序运行时的内存使用情况。

使用GC dump可以帮助开发人员找出内存泄漏、内存溢出等问题,以及分析内存使用情况,优化程序性能。

GC dump的生成方式有多种,可以通过命令行参数、JMX控制台、调试工具等方式生成。一般情况下,建议使用jmap命令生成GC dump文件,具体命令如下:

jmap -dump:format=b,file=heapdump.bin

其中,format参数指定生成文件格式为二进制格式,file参数指定生成的文件名称,pid参数指定Java进程的进程ID。

生成GC dump文件后,可以使用各种分析工具,如MAT、VisualVM等工具对文件进行分析。

15.5 垃圾清除阶段 - 标记-清除算法

  • 执行过程:堆中有效空间被耗尽的时候,就会STW然后进行标记与清除
  • 标记:从根节点开始遍历,标记所有被引用的对象
  • 清除:对堆内存从头到尾遍历。遍历到被标记的部分就将其回收

在这里插入图片描述

  • 缺点:需要STW,用户体验差
  • 这种方式清理出的内存空间不连续,产生内存碎片

15.6 垃圾清除阶段 - 标记-复制算法

将内存空间分为两块。每次使用一块,GC时将正在使用部分的存活对象复制至另一块中,再将本块所有对象清除即可。
在这里插入图片描述

  • 优点:实现简单,运行高效,保证GC后空间连续性
  • 缺点:需要两倍运行空间
  • 新生代大量对象需要GC,大量清除少量复制,用本方法比较好。

15.7 垃圾清除阶段 - 标记-压缩算法

在这里插入图片描述
效果等同于一次标记-清除算法后,进行一次内存碎片整理

  • 优点:优化了之前标记-清除算法的内存分散问题,也没有标记-复制算法的内存减半问题
  • 缺点:效率低,调整引用地址有开销,STW时间长
    在这里插入图片描述

15.8 小结

目前几乎所有GC算法都采用分代收集算法进行垃圾回收

16. 垃圾回收相关概念

16.1 System.gc()的理解

System.gc() 方法只是建议 JVM 执行垃圾回收,但具体是否执行还取决于 JVM 的实现和当前系统的资源情况。在某些情况下,JVM 可能会忽略这个建议。因此,开发者不应该依赖 System.gc() 方法来确保垃圾回收的执行。

16.2 内存溢出与内存泄漏

  • 内存溢出:没有空闲内存,且GC也无法提供更多内存
  • 内存泄漏:对象不会被程序用到了,但GC又不能回收它们的情况

16.3 Stop the world

指GC过程中应用程序的停顿。
STW由JVM在后台自动发起和完成。
所有GC都有这个事件,不可避免,只能尽可能缩短

16.4 安全点与安全区域

  • 安全点:GC能够安全暂停程序并执行GC的时间点
  • 安全区域:这段时间内,对象的引用关系不会发生变化,在这个区域内任何时间GC都安全。(相当于扩展的安全点)

16.5 强软弱虚引用

  • 强引用:程序中最常见也是默认的引用。只要强引用的对象可触及,JVM宁肯报OOM也不会回收。
    强引用可能导致内存泄漏

  • 软引用:迫不得已在OOM之前才会尝试回收。
    实现方式:java.lang.SoftReference

  • 弱引用:只要触发GC就回收。
    但是GC线程优先级不高,所以弱引用的对象可能能活一段时间
    实现方式:java.lang.WeakReference

  • 虚引用:跟没有一样。设置虚引用的唯一目的就是跟踪GC的过程(在这个对象被回收时会收到一个通知)

17. 垃圾回收器

17.1 分类

  • 并行与串行
  • 并发式与独占式:并发式指应用程序与GC交替进行;独占式指GC运行时会停止应用程序的运行
  • 压缩式与非压缩式:GC后是否压缩内存碎片
  • 按工作区间区分:新生代,老年代回收器

17.2 性能指标

  • 吞吐量:用户代码运行时间占总时间的比例
  • 暂停时间:GC时应用程序被暂停的时间
  • 收集频率:GC发生的频率
  • 内存占用:GC占用内存大小
  • 快速

17.3 不同垃圾收集器概述

  • 串行回收器:Serial,Serial Old
  • 并行回收器:ParNew,Parallel Scavenge,Parallel Old
  • 并发回收器:CMS ,G1

在这里插入图片描述

17.4 串行回收 - Serial/Serial Old

  • 串行,Serial用于新生代,复制算法,STW机制;Serial Old用于老年代
  • 简单高效但单核,现在不怎么用了
    在这里插入图片描述

17.5 ParNew回收器

相当于Serial的并行版本
同样采用复制算法,STW机制,新生代回收,只是采用并行回收
在这里插入图片描述
多核情况下比Serial效果更好,但单核情况下会差

17.6 Parallel Scavenge 与 Parallel Old

  • Parallel Scavenge
    年轻代回收,复制算法,并行回收,STW机制,这些和ParNew一样
    但Parallel Scavenge以吞吐量优先
  • Parallel Old
    老年代,并行回收,STW机制,标记-压缩算法。
    两者组合使用,效果不错
    Java8中的默认垃圾收集器
    在这里插入图片描述

17.7 CMS收集器

老年代收集器,标记-清除算法,STW,真正意义下的并发收集器(用户线程与GC线程并发工作),尽可能减少停顿时间
CMS不能配合Parallel Scavage工作,所以新生代只能选择ParNew或Serial

在这里插入图片描述
CMS工作原理:四个阶段

  • 初始标记阶段:STW,标记出GC Roots关联的对象,非常快
  • 并发标记阶段:不STW,从GC Roots开始遍历整个对象图,时间较长但不停顿
  • 重新标记阶段:修正并发标记期间变动的标记记录,停顿时间比1长但比2短
  • 并发清除阶段:清理,并发运行

还是需要STW的,但整体停顿时间较低
CMS需要足够内存,所以不能等老年代满了才CMS GC,需要老年代到一定内存阈值就开始CMS
因为是标记-清除算法,所以会有内存碎片

以上GC回收器的选用:

在这里插入图片描述

17.8 G1回收器

全功能垃圾收集器,面向服务端应用,适应不断扩大的内存与CPU核数,JDK 9以后的默认垃圾回收器
侧重于延迟可控下获得较高吞吐量

特点:

  • 并行与并发:G1回收器可利用多核并行执行,且G1与工作线程可以并发工作
  • 分代收集:G1依然会区分老年代和新生代,但不是传统意义的分区了。
    如下图所示:内存被划分成一个个Region。Region内部用复制算法,但整体的块可以看作标记-压缩算法。
  • 停顿时间可预测
  • 大内存下G1好用,小内存下CMS好用。平衡点在6-8G之间

在这里插入图片描述
G1对内存分块时新增了一种Humongous快,用于储存大对象

G1 GC过程:
在这里插入图片描述

17.9 垃圾回收器总结

截至Java 1.8
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值