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

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] 
Heap
 def 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 1056768K
  class 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] 
Heap
 def 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 1056768K
  class 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.kler.cn/a/590286.html

相关文章:

  • k8s环境部署
  • Kubernetes集群版本升级
  • 【开源免费】基于SpringBoot+Vue.JS失物招领平台(JAVA毕业设计)
  • vlc录制的视频伪时长修复方法
  • Python中存储数据——json模块
  • JVM常用概念之堆未提交
  • ios app第一次上架遇到的审核问题
  • Kotlin 中 let 方法的作用和使用场景
  • MATLAB 控制系统设计与仿真 - 27
  • 【机器人-基础知识】标定 - 相机标定全解
  • 【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(6)
  • json字符串转对象,对象转JSON
  • c++基础知识-图论进阶
  • ArcGIS10.X影像智能下载!迁移ArcGIS Pro批量智能高清影像下载工具至ArcGIS!
  • Matlab 汽车悬架系统动力学建模与仿真
  • Docker封装镜像、分发、部署实践:nginx
  • 轨道交通CPU+FPGA控制器,支持codesys/vxWorks/翼辉等实时系统
  • 基于eNSP的IPV4和IPV6企业网络规划
  • 商用电脑VS家用电脑,为何企业更需要华硕NUC 14 Pro?
  • 【GIS】重要技术3DGS