当前位置: 首页 > news >正文

4.JVM-垃圾回收介绍

记录个人学习中记录笔记,如有错误请您指正,谢谢🙏

垃圾回收器发展史

传统垃圾回收: 分代回收 不同代有不同的垃圾回收机制

保底

标记清除算法

垃圾识别算法

引用计数法

缺陷:下图2 出现循环引用 无法解决

可达性分析

大部分(Java,python,go等)都在用这种方式

常见的根对象(GCRoots):

  • 方法区中的常量引用的对象
  • 方法区中的类静态属性引用的对象
  • 本地方法栈中JNI的引用的对象
  • 虚拟机栈(栈帧中的本地变量表)中引用的对象

垃圾清除算法

标记-清除法 (基本不用)

问题: 容易产生无法使用的内存碎片

比如标记可用块每块2MB,实际使用1.9MB,剩余0.1MB就是内存碎片,无法处理

复制法 (适合新生代)

问题:浪费内存空间

存货对象少垃圾对象多的前提下效果好

标记-压缩算法 (适合老年代)

问题:速度慢

三种清除方法比较

新生代垃圾回收器

GC日志内容

/***  jdk17: -Xlog:gc*=info:stdout:time,uptime,level,tags*  jdk8:*  -Xmx20M* -Xmn10M* -XX:+PrintGCDetails* -XX:+UseSerialGC* -XX:+PrintGCTimeStamps*  -XX:+PrintGCDateStamps   # 绝对时间* -XX:SurvivorRatio=8*/
public class GC_Serial {/*-Xmx20M-Xmn10M-XX:+PrintGCDetails-XX:+UseSerialGC-XX:+PrintGCTimeStamps-XX:SurvivorRatio=8*/private static final int size = 1024 * 256;public static void main(String[] args) {
//        System.gc();for (int i = 0; i < 30; i++) {byte[] date = new byte[size];}}/*** Allocation Failure:  // 分配内存失败* metadata space exhausted:  // 元数据空间耗尽* system.gc() invoked:  // 调用了System.gc() => full gc*//*** 各种垃圾回收器常见的类型:* serial => DefNew* parNew => ParNew* Parallel => PSYoungGen* Parallel Old => ParoldGen*/}
  • def new generation:新生代
  • tenured generation:老年代
  • metaspace:元空间
    • committed:下次分配可以分配多大空间
    • reserved:最大可用空间多大
0.709: [GC (Allocation Failure) 0.709: [DefNew: 8153K->731K(9216K), 0.0017122 secs] 8153K->731K(19456K), 0.0018048 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heapdef new generation   total 9216K, used 3021K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K,  27% used [0x00000000fec00000, 0x00000000fee3c460, 0x00000000ff400000)from space 1024K,  71% used [0x00000000ff500000, 0x00000000ff5b6fc8, 0x00000000ff600000)to   space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)tenured generation   total 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)the space 10240K,   0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000)Metaspace       used 3226K, capacity 4486K, committed 4864K, reserved 1056768Kclass space    used 332K, capacity 386K, committed 512K, reserved 1048576K

Serial串行回收器-最基本的垃圾回收器

  • 新生代 SerialNew 老年代 SerialOld
  • 新生代使用<font style="background-color:#FBDE28;">复制算法</font> 老年代采用 <font style="background-color:#FBDE28;">标记压缩</font>

测试代码
/*-Xmx20M-Xmn10M-XX:+PrintGCDetails-XX:+UseSerialGC-XX:+PrintGCTimeStamps-XX:SurvivorRatio=8*/private static final int size = 1024 * 256;public static void main(String[] args) {
//        System.gc();for (int i = 0; i < 30; i++) {byte[] date = new byte[size];}}/*** Allocation Failure:  // 分配内存失败* metadata space exhausted:  // 元数据空间耗尽* system.gc() invoked:  // 调用了System.gc() => full gc*//*** 各种垃圾回收器常见的类型:* serial => DefNew* parNew => ParNew* Parallel => PSYoungGen* Parallel Old => ParoldGen*/
  • def new generation:新生代
  • tenured generation:老年代
  • metaspace:元空间
    • committed:下次分配可以分配多大空间
    • reserved:最大可用空间多大
0.709: [GC (Allocation Failure) 0.709: [DefNew: 8153K->731K(9216K), 0.0017122 secs] 8153K->731K(19456K), 0.0018048 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heapdef new generation   total 9216K, used 3021K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K,  27% used [0x00000000fec00000, 0x00000000fee3c460, 0x00000000ff400000)from space 1024K,  71% used [0x00000000ff500000, 0x00000000ff5b6fc8, 0x00000000ff600000)to   space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)tenured generation   total 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)the space 10240K,   0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000)Metaspace       used 3226K, capacity 4486K, committed 4864K, reserved 1056768Kclass space    used 332K, capacity 386K, committed 512K, reserved 1048576K

ParNew回收器

  • 只能在新生代使用,一般配合老年代 CMS 回收器,比Serial多了并行回收

测试代码
   /*-Xmx20M-Xmn10M-XX:+PrintGCDetails-XX:+UseParNew-XX:+PrintGCTimeStamps-XX:SurvivorRatio=8*/private static final int size = 1024 * 256;public static void main(String[] args) {
//        System.gc();for (int i = 0; i < 30; i++) {byte[] date = new byte[size];}}/*** Allocation Failure:  // 分配内存失败* metadata space exhausted:  // 元数据空间耗尽* system.gc() invoked:  // 调用了System.gc() => full gc*//*** 各种垃圾回收器常见的类型:* serial => DefNew* parNew => ParNew* Parallel => PSYoungGen* Parallel Old => ParoldGen*/

Parallel回收器

JDK8默认的回收器

  • Paralle和ParNew机制类似,通过自适应调节来决定回收时机、和回收频率,达到“吞吐量”有限
  • 和ParNew的区别在于,进入“SafePoints”的时机不一样
  • 在年轻代叫做ParalleNew 老年代叫做 ParalleOld

老年代垃圾回收期

Parallel Old:3.4部分介绍

Serial Old:3.2部分介绍

CMS回收器

没有一个jdk版本设置他默认清理器

JDK14已经移除

优点:

  • 并发收集
  • 停顿时间短

缺点:

  • **处理器资源非常敏感: **收集过程中会开启多个线程
  • 产生浮动垃圾:在并发标记和并发清理阶段,用户线程产生的新垃圾,可能出现Concurrent Model Failure失败而导致另一次Fu GC的产生
  • 空间碎片过多:因为采用的标记清除算法,会产生标记清除算法的问题

初始标记(step-1)

会STW

并发标记(step-2)

重新标记(step-3)

会STW

并发清除(step-4)

CMS 回收过程

初始标记

新生代引用的老年代的活的对象

并发标记

标记第一步找出的GC Roots节点,往下遍历

预清理阶段

将第一步第二步没有引用的节点提前标记,本质第一步第二步的增量操作

为的是减少重新标记的时间

可中断的预处理

把重新标记的工作提前做

重新标记

DirtyCard: 预清理阶段,检查看看是否需要清理

并发清理

并发重置

其他问题

MinorGC vs YoungGC

一样的概念,都是针对 年轻代或者叫做新生代的清理

FullGC vs OldGC

G1之前两者都是一样的,都是老年代的垃圾回收

FullGC 表示 新生代老年代永久代的清理更合理

MajorGC

含义不清

FullGC什么时候出发

System.gc()

手动触发FullGC


http://www.mrgr.cn/news/94883.html

相关文章:

  • Git——分布式版本控制工具使用教程
  • 流量分析实践
  • 函数(函数的概念、库函数、自定义函数、形参和实参、return语句、数组做函数参数、嵌套调用和链式访问、函数的声明和定义、static和extern)
  • AirtestIDE用法
  • 大数据学习(69)-数据架构
  • 蓝桥杯嵌入式赛道复习笔记2(按键控制LED灯,双击按键,单击按键,长按按键)
  • LeetCode Hot 100:1.两数之和、49.字母异位词分组、128.最长连续序列、283.移动零、11.盛水最多的容器
  • 11.anaconda中的jupyter使用、及整合dataspell
  • 【华为OD-E卷 -122 字符统计及重排 100分(python、java、c++、js、c)】
  • 微服务》》Kubernetes (K8S)安装
  • 【蓝桥杯每日一题】3.16
  • 使用Dependency Walker和Beyond Compare快速排查dll动态库损坏或被篡改的问题
  • hubilder打包ios app, 并上传TestFlight
  • 用uv管理python环境/项目(各种应用场景)
  • WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)深度解析与实战复现
  • PosterRender 实现微信下程序 分享商品生成海报
  • [蓝桥杯 2023 省 B] 飞机降落
  • 算法刷题记录——LeetCode篇(8) [第701~800题](持续更新)
  • 本地部署DeepSeek-R1(Dify升级最新版本、新增插件功能、过滤推理思考过程)
  • 【深度学习|目标检测】YOLO系列anchor-based原理详解