JVM入门学习笔记——上篇:内存与垃圾回收(14-16)

文章目录

  • 14、垃圾回收概述
    • 一、什么是垃圾
      • 大厂面试题
      • 什么是垃圾?
    • 二、为什么需要GC
    • 三、早期垃圾回收
    • 四、Java垃圾回收机制
      • 担忧
      • 应该关心的回收区域
  • 15、垃圾回收相关算法
    • 一、标记阶段:引用计数算法
      • 垃圾标记阶段:对象存活判断
      • 引用计数算法
      • 循环引用
      • 证明Java并不是用引用计数算法的例子
      • 小结
    • 二、标记阶段:可达性分析算法
      • GC Roots
        • 注意
    • 三、对象的finalization机制
      • 生存还是死亡?
      • 具体过程
    • 四、MAT与JProfiler的GC Roots溯源
      • MAT
      • 获取dump文件
      • JProfiler
    • 五、清除阶段:标记-清除算法
      • 垃圾清除阶段
      • 标记-清除(Mark-Sweep)算法
        • 缺点
    • 六、清除阶段:复制算法
      • 复制(Copying)算法
        • 优缺点
        • 应用场景
    • 七、清除阶段:标记-压缩(整理)算法
      • 标记-压缩(Mark-Compact)算法
        • 优缺点
      • 指针碰撞
    • 八、小结
      • 三种清除阶段的算法对比
    • 九、分代收集算法
    • 十、增量收集算法、分区算法
      • 增量收集算法
        • 缺点
      • 分区算法
  • 16、垃圾回收相关概念
    • 一、System.gc()的理解
    • 二、内存溢出与内存泄漏
      • 内存溢出(OOM)
      • 内存泄漏(Memory Leak)
        • 内存泄漏的例子
    • 三、Stop The World(STW)
    • 四、垃圾回收的并行与并发
      • 并发(Concurrent)
      • 并行(Parallel)
      • 并发 vs 并行
      • 垃圾回收的并发与并行
    • 五、安全点与安全区域
      • 安全点(Safe Point)
      • 安全区(Safe Region)
    • 六、引用
      • 强引用(Strong Reference):不回收
      • 软引用(Soft Reference):内存不足即回收
      • 弱引用(Weak Reference):发现即回收
      • 虚引用(Phantom Reference):对象回收跟踪
      • 终结器引用(Final Reference)

14、垃圾回收概述

一、什么是垃圾

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第1张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第2张图片

大厂面试题

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第3张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第4张图片

什么是垃圾?

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第5张图片

二、为什么需要GC

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第6张图片

三、早期垃圾回收

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第7张图片
内存泄漏:无法回收的垃圾过多。(无法回收的垃圾:已经没有用但还是有被引用的对象)
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第8张图片

四、Java垃圾回收机制

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第9张图片

担忧

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第10张图片

应该关心的回收区域

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第11张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第12张图片

15、垃圾回收相关算法

一、标记阶段:引用计数算法

垃圾标记阶段:对象存活判断

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第13张图片

引用计数算法

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第14张图片
当对象的引用计数器为0时,直接进行GC。

循环引用

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第15张图片
Java并不是选用引用计数算法,而是选可达性分析算法,所以循环链表无法回收在引用计数算法中无法GC,但是在Java中可以GC。

证明Java并不是用引用计数算法的例子

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第16张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第17张图片

进行了垃圾回收,并且成功回收了这两个对象,如果Java使用的是引用计数算法,那么这两个对象会因为循环调用而无法GC掉,所以Java并不是用引用计数算法。

小结

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第18张图片

二、标记阶段:可达性分析算法

可达性分析算法又称根搜索算法、追踪性垃圾收集。
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第19张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第20张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第21张图片

GC Roots

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第22张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第23张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第24张图片

注意

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第25张图片

三、对象的finalization机制

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第26张图片
finalize()方法是一个空方法。
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第27张图片

生存还是死亡?

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第28张图片
对象有三种状态:可触及的,可复活的,不可触及的。

  • 可触及的:GC Roots的引用链上,不可以GC。
  • 可复活的:已经不在GC Roots的引用链上,但是对象重写了finalize()方法,并且方法里可能复活自己。
  • 不可触及的:已经不在GC Roots的引用链上,并且没有重写finalize()方法或重写的finalize()方法里没有复活自己。

具体过程

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第29张图片
如果是调用finalize()方法后复活的对象,当下一次没在GC Roots引用链上时,会变成不可触及的状态,没有再次复活的机会,因为finalize()方法只能调用一次

四、MAT与JProfiler的GC Roots溯源

MAT

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第30张图片
https://www.eclipse.org/mat/downloads.php

获取dump文件

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第31张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第32张图片

JProfiler

https://www.ej-technologies.com/products/jprofiler/overview.html

五、清除阶段:标记-清除算法

垃圾清除阶段

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第33张图片

标记-清除(Mark-Sweep)算法

标记-清除算法:当内存被耗尽时,STW停止整个程序,然后进行GC。
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第34张图片
被标记的对象是不回收的对象(非垃圾对象/可达对象),类似白名单。
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第35张图片
标记时,递归遍历使用GC Roots的引用链,给引用链上的所有对象加上标记,被标记对象不进行回收。

缺点

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第36张图片
垃圾对象清除也并不是直接删除,而是将清除的对象的地址保存在空闲地址列表里,当下一个新对象创建时,新对象覆盖掉被清除对象。

六、清除阶段:复制算法

复制(Copying)算法

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第37张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第38张图片

优缺点

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第39张图片
这里应该是垃圾对象少的话,复制算法不理想,因为复制算法复制的是存活对象,GC时,如果存活对象很多,那么需要复制的对象就很多,并且还需要把对象的引用地址进行修改,所以复制算法如果垃圾对象少的话就不理想了,视频里的PPT这里写错了。

应用场景

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第40张图片

七、清除阶段:标记-压缩(整理)算法

标记-压缩(Mark-Compact)算法

标记-压缩算法又称标记-整理算法。
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第41张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第42张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第43张图片
标记压缩算法是在标记清除算法的基础上增加了对象内存碎片的整理。
标记压缩算法不需要修改存活对象的内存地址,而标记压缩算法需要。

优缺点

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第44张图片

指针碰撞

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第45张图片

八、小结

三种清除阶段的算法对比

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第46张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第47张图片

九、分代收集算法

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第48张图片

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第49张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第50张图片

十、增量收集算法、分区算法

增量收集算法

缺点

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第51张图片

分区算法

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第52张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第53张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第54张图片

16、垃圾回收相关概念

一、System.gc()的理解

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第55张图片

  • System.gc()只是提醒JVM垃圾回收器执行GC,但不一定就会马上进行回收。
  • Runtime.getRuntime().gc()与System.gc()相同。
  • System.runFinalization()是强制调用失去引用的对象的finalization()方法。

二、内存溢出与内存泄漏

内存溢出(OOM)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第56张图片

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第57张图片
如果内存不够,会先进行GC,GC后还是没空间才报OOM;如果创建的对象大于堆的最大值,那么并不会进行GC,而是直接报OOM。

内存泄漏(Memory Leak)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第58张图片
内存泄漏可以会出现OOM。
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第59张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第60张图片

内存泄漏的例子

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第61张图片

  1. 单例模式的类中引用了外部对象,因为单例的类生命周期很长,所以引用的外部对象不能及时的进行GC,从而引发内存泄漏的问题。
  2. 一些资源因为未调用close()方法进行关闭,从而引发内存泄漏的问题。

三、Stop The World(STW)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第62张图片
因为GC Roots是随时都在变化的,而GC又是根据GC Roots进行可达性分析的,所以需要先暂停所有用户线程,然后再进行垃圾回收。
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第63张图片

四、垃圾回收的并行与并发

并发(Concurrent)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第64张图片

并行(Parallel)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第65张图片

并发 vs 并行

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第66张图片

垃圾回收的并发与并行

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第67张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第68张图片

五、安全点与安全区域

安全点(Safe Point)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第69张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第70张图片

安全区(Safe Region)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第71张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第72张图片

六、引用

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第73张图片

这四种引用都是可达的。

强引用(Strong Reference):不回收

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第74张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第75张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第76张图片

软引用(Soft Reference):内存不足即回收

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第77张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第78张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第79张图片

弱引用(Weak Reference):发现即回收

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第80张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第81张图片

虚引用(Phantom Reference):对象回收跟踪

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第82张图片
JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第83张图片

终结器引用(Final Reference)

JVM入门学习笔记——上篇:内存与垃圾回收(14-16)_第84张图片

下一篇笔记:JVM入门学习笔记——上篇:内存与垃圾回收(17)

学习视频(p134-p168):https://www.bilibili.com/video/BV1PJ411n7xZ?p=134

你可能感兴趣的:(JVM)