首页 > 编程语言 >Java垃圾回收全过程

Java垃圾回收全过程

时间:2023-09-03 21:32:22浏览次数:38  
标签:Full Java 标记 对象 Mark GC 全过程 JVM 垃圾

JVM中一次完整的垃圾回收(GC)过程。这里以HotSpot虚拟机为例,并将参考其中的一种常用的垃圾回收器:G1(Garbage-First)。

堆的划分

在HotSpot JVM中,堆(Heap)通常被划分为以下几个部分:

  • 年轻代(Young Generation): 这部分进一步分为Eden区和两个Survivor区(S0和S1)。
  • 老年代(Old Generation): 存放长时间存活的对象。
  • 元空间(Metaspace): 存放类的元数据。

阶段1:Minor GC

1.1 初始标记(Initial Mark)

  • 停止所有的应用线程(Stop-The-World, STW)
  • 标记从GC Roots直接可达的对象

1.2 并发标记(Concurrent Mark)

  • 在应用线程运行的同时,标记通过已标记对象间接可达的对象

1.3 最终标记(Final Mark)

  • 处理在并发标记阶段发生变化(如新创建的对象)的标记

1.4 清除与复制(Evacuation)

  • 删除未标记的对象,并将存活的对象复制到Survivor区或Old区

在HotSpot JVM中,当对象在年轻代(Young Generation)的Survivor区经过一定次数的Minor GC后仍然存活,它们会被晋升(promoted)到老年代(Old Generation)。这个晋升过程也被称为“老年代担保”(Tenuring Threshold)。这里有几个关键点需要注意:

晋升阈值(Tenuring Threshold)

JVM有一个称为“晋升阈值”(Tenuring Threshold)的设置,该设置定义了一个对象在被晋升到老年代之前必须经历多少次Minor GC。这个阈值可以通过JVM参数 -XX:MaxTenuringThreshold-XX:InitialTenuringThreshold 来设置。

担保机制

当Minor GC发生时,JVM需要确保所有存活的对象都有足够的空间。如果Survivor区没有足够的空间来容纳这些对象,JVM有两种选择:

  1. 尝试在老年代中找到空间: 如果老年代有足够的空间来容纳这些对象,则这些对象会被直接晋升到老年代,即使它们的年龄没有达到晋升阈值。
  2. 触发Full GC: 如果老年代没有足够的空间来容纳这些对象,JVM可能会选择触发一次Full GC来清理整个堆(包括老年代)。

动态调整

在运行时,JVM可能会动态地调整晋升阈值。这是基于之前GC活动的统计数据来进行的,目的是优化内存使用和减少Full GC的次数。

为什么需要担保机制?

担保机制的目的是为了确保堆内存的有效利用和GC性能的优化。通过将经常存活的对象移动到老年代,Minor GC可以更高效地回收年轻代,因为老年代的GC通常较少发生。

阶段2:Full GC(Major GC)

Full GC通常会清理整个堆空间,包括年轻代和老年代。

2.1 初始标记(Initial Mark)

  • STW事件
  • 标记所有从GC Roots直接可达的对象

2.2 根区域扫描(Root Region Scanning)

  • 标记所有从"根区域"(如老年代)可达的对象

2.3 并发标记(Concurrent Mark)

  • 与应用线程并行,标记所有存活的对象

2.4 最终标记(Final Mark)

  • STW事件
  • 处理在并发标记期间发生变化的标记

2.5 筛选回收(Cleanup)

  • 清除不再使用的内存区域,并为即将发生的分配做准备

额外阶段:元空间回收(Metaspace Collection)

  • 如果元空间满了,会触发Full GC来清理类的元数据

监控和调试

  • JVM提供了许多标志和工具来监控和调试GC行为,如-XX:+PrintGCDetails和JVisualVM等

标签:Full,Java,标记,对象,Mark,GC,全过程,JVM,垃圾
From: https://blog.51cto.com/u_15567202/7343369

相关文章

  • 《Java编程思想第四版》学习笔记22
    注意下面这两句话:1、针对g()和main(),Throwable类必须在违例规格中出现,因为fillInStackTrace()会生成一个Throwable对象的句柄。由于Throwable是Exception的一个基础类,所以有可能获得一个能够“掷”出的对象(具有Throwable属性),但却并非一个Exception(违例)。因此,在main()......
  • Java面试之用一个栈实现另一个栈的排序
    一题目一个栈中元素的类型为整数,现在想将该栈从顶到底按从大到小的顺序排序,只许申请一个栈。除此之外可以申请新的变量,但不能申请额外的数据结构。如何完成排序?二要求将要排序的栈记为stack,申请的辅助栈记为help。在stack上执行pop操作,弹出的元素记为cur。1.如果cur小于或等于hel......
  • 无涯教程-JavaScript - TTEST函数
    TTEST函数取代了Excel2010中的T.TEST函数。描述该函数返回与学生t检验相关的概率。使用TTEST来确定两个样本是否可能来自均值相同的相同两个基础总体。语法TTEST(array1,array2,tails,type)争论Argument描述Required/OptionalArray1Thefirstdataset.Required......
  • Java中使用ProcessBuilder执行命令
    在Java中我们可以使用ProcessBuilder来创建一个进程并执行命令。在使用前我们首先了了解下两个程序。一、认识命令行解释程序不论在windows中还是linux中都可以通过命令行方式来执行某些程序或脚本,而解析命令行的程序被称为shell,其本身是一种命令行解释器,用于与操作系统进行交互和......
  • Java对象从创建到回收全过程
    先了解下Java虚拟机内存组成,当Java虚拟机启动后,会将系统分配给JVM的空间逻辑上划分为堆、虚拟机栈、本地方法栈、方法区、程序计数器五个部分,如下图所示:堆:放置new出来的对象、数组虚拟机栈:线程运行前,会给其分配一个线程栈空间,线程中每个方法执行都会生成一个栈帧放入线程栈中,栈帧里......
  • Java内存模型(JMM)详解
    面试官:讲讲什么是JMMJMM(Java内存模型)详解1什么是JMM?JMM就是Java内存模型(JavaMemoryModel)JMM是一个抽象的概念,他描述的是和多线程相关的一组规范,需要各个JVM的实现来遵守JMM规范,以便于开发者可以利用这些规范,更方便的开发多线程程序。这样一来,即使同一个程序在不同的虚拟......
  • 无涯教程-JavaScript - TINV函数
    TINV函数取代了Excel2010中的T.INV.2T函数。描述该函数返回学生t分布的两尾逆。语法TINV(probability,deg_freedom)争论Argument描述Required/OptionalProbabilityTheprobabilityassociatedwiththetwo-tailedStudent'st-distribution.RequiredDeg_freedom......
  • java基础-方法method-day05
    1.语法[修饰符]返回值类型方法名(形参列表){逻辑主体}publicclassTestMethod01{ publicstaticintadd(intnum1,intnum2){ intsum=0; sum+=num1; sum+=num2; returnsum; } publicstaticvoidmain(String[]args){ intsum1=add(10......
  • JavaGuide基础3
    异常Exception和ErrorException:程序本身可以处理的异常,可以通过catch来进行捕获。Exception又可以分为CheckedException(受检查异常,必须处理)和UncheckedException(不受检查异常,可以不处理)。Error:Error属于程序无法处理的错误,不建议通过catch捕获。例如Jav......
  • JavaScript – 小技巧 Tips
    1e6等价于1+后面6个零console.log(1e6===1_000_000); 模拟C#的Record DeconstructclassSizeimplementsIterable<number>{constructor(publicwidth:number,publicheight:number){}*[Symbol.iterator](){......