JVM垃圾回收的普遍步骤

JVM(Java Virtual Machine)进行垃圾回收时,通常遵循以下步骤。不同的垃圾收集器可能会有一些不同的实现细节,但基本步骤和思想大致相同。以下是一般的垃圾回收过程的主要步骤:

1. 标记阶段(Marking Phase)

  • 可达性分析:JVM 会从根对象(GC Roots)开始,遍历所有引用并标记所有可达对象。
    • GC Roots 包括:
      • 活动线程栈中的局部变量
      • 静态变量
      • JNI 引用
      • 已加载的类
  • 标记对象:所有被引用的对象都会被标记为可达对象。

2. 清除阶段(Sweeping Phase)

  • 删除不可达对象:未被标记的对象被视为垃圾,将会被删除。
  • 回收空间:回收被删除对象占用的内存空间。

3. 压缩阶段(Compacting Phase)

  • 对象移动:将存活的对象压缩到内存的一端,以便腾出连续的内存空间。
  • 更新引用:更新所有指向被移动对象的引用,以确保引用的正确性。

4. 分代回收(Generational Collection)

  • 新生代(Young Generation):主要用于存放新创建的对象,包括以下三个区域:
    • Eden 区:大部分新对象首先在这里分配。
    • Survivor 区:两个 Survivor 区(S0 和 S1),用于在新生代之间复制存活的对象。
    • Minor GC:当 Eden 区满时触发 Minor GC,将存活对象复制到 Survivor 区或晋升到老年代。
  • 老年代(Old Generation):用于存放生命周期较长的对象。
    • Major GC/Full GC:当老年代满时触发 Major GC 或 Full GC,这个过程通常比 Minor GC 更耗时。

5. 特殊的垃圾回收器

  • Serial GC:单线程垃圾收集器,适用于单处理器环境。
  • Parallel GC:多线程垃圾收集器,适用于多处理器环境,着重于吞吐量。
  • CMS(Concurrent Mark-Sweep)GC:并发标记清除垃圾收集器,旨在减少停顿时间。
  • G1(Garbage-First)GC:分区垃圾收集器,兼顾低停顿和高吞吐量,适用于大堆内存。

示例流程

以下是一个典型的垃圾回收过程(以 G1 GC 为例):

  1. 初始标记(Initial Marking):标记从 GC Roots 直接可达的对象。这阶段会暂停所有应用线程(STW)。
  2. 并发标记(Concurrent Marking):遍历对象图,标记所有可达对象。此阶段与应用线程并发执行。
  3. 最终标记(Final Marking):处理在并发标记阶段发生变化的对象。会有短暂的 STW。
  4. 筛选回收(Live Data Counting and Evacuation):计算存活对象并选择回收区域,将存活对象移动到新区域,回收旧区域。

垃圾回收示意图

1. 标记阶段(Marking Phase)- 可达性分析:GC Roots -> 标记所有可达对象2. 清除阶段(Sweeping Phase)- 删除不可达对象 -> 回收内存空间3. 压缩阶段(Compacting Phase)- 移动存活对象 -> 更新引用4. 分代回收(Generational Collection)- 新生代(Young Generation):Eden、Survivor -> Minor GC- 老年代(Old Generation) -> Major GC/Full GC5. 特殊的垃圾回收器- Serial GC、Parallel GC、CMS GC、G1 GC

总结

JVM 的垃圾回收过程包括标记、清除、压缩等阶段,结合分代回收机制来高效地管理内存。不同的垃圾收集器根据不同的需求和环境进行优化,以达到最佳的性能和最小的停顿时间。了解这些步骤和原理可以帮助开发者优化 Java 应用的性能和稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/852732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小白都能看懂的 “栈”

什么是栈?首先引用维基百科的解释: 栈(stack)是计算机科学中的一种抽象资料类型,只允许在有序的线性资料集合的一端(称为堆栈顶端,top)进行加入数据(push)和移…

Go语言结构体内嵌接口

前言 在golang中,结构体内嵌结构体,接口内嵌接口都很常见,但是结构体内嵌接口很少见。它是做什么用的呢? 当我们需要重写实现了某个接口的结构体的(该接口)的部分方法,可以使用结构体内嵌接口。 作用 继承赋值给接口…

信号与系统实验MATLAB-实验1-信号的MATLAB表示及信号运算

实验1-信号的MATLAB表示及信号运算 一、实验目的 1、掌握MATLAB的使用; 2、掌握MATLAB生成信号波形; 3、掌握MATLAB分析常用连续信号; 4、掌握信号运算的MATLAB实现。 二、实验内容 编写程序实现下列常用函数,并显示波形。…

PyTorch -- Visdom 快速实践

安装:pip install visdom 注:如果安装后启动报错可能是 visdom 版本选择问题 启动:python -m visdom.server 之后打开出现的链接 http://localhost:8097Checking for scripts. Its Alive! INFO:root:Application Started INFO:root:Working…

数据网格和视图入门

WinForms数据网格(GridControl类)是一个数据感知控件,可以以各种格式(视图)显示数据。本主题包含以下部分,这些部分将指导您如何使用网格控件及其视图和列(字段)。 Grid Control’s…

BUUCTF-Web题目1

目录 [HCTF 2018]admin 1、题目 2、知识点 3、思路 [极客大挑战 2019]BuyFlag 1、题目 2、知识点 3、思路 [HCTF 2018]admin 1、题目 2、知识点 BP暴力破解密码 3、思路 打开题目,查看页面源代码,发现需要admin用户才可以登录 这一台有很多解法…

redis清空list

redis list清空 要清空Redis中的list,您可以使用LTRIM命令。Redis Ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 下标 0 表示列表的第一个元素,以 1 表示…

LeetCode | 20.有效的括号

这道题就是栈这种数据结构的应用,当我们遇到左括号的时候,比如{,(,[,就压栈,当遇到右括号的时候,比如},),],就把栈顶元素弹出,如果不匹配,则返回False,当遍历完所有元素后…

实体店如何通过私域获取流量?

随着互联网的快速发展和消费者购物习惯的变化,私域流量对于实体店的重要性日益凸显。私域流量是指企业在自己的平台上沉淀的、可以免费使用、多次利用的流量,如微信生态下的朋友圈、公众号、企业微信等。对于实体店而言,有效利用私域流量不仅…

K8s 卷快照类

卷快照类 卷快照类 这个警告信息通常出现在使用 kubectl 删除 Kubernetes 集群资源时,如果尝试删除的是集群作用域(cluster-scoped)的资源,但指定了命名空间(namespace),就会出现这个警告。 集…

基于PointNet / PointNet++深度学习模型的激光点云语义分割

一、场景要素语义分割部分的文献阅读笔记 1.1 PointNet PointNet网络模型开创性地实现了直接将点云数据作为输入的高效深度学习方法(端到端学习)。最大池化层、全局信息聚合结构以及联合对齐结构是该网络模型的三大关键模块,最大池化层解决了…

72、AndroidStudio 导入项目Connect timed out错误解决

一、背景: 开发过程中难免会 clone 其他的项目,clone 或者下载成功之后。使用 android studio 打开项目时经常遇到 Connect timed out错误如图所示: 二、分析原因: 1、既然链接超时,肯定是 android studio 在运行…

包装类的应用

一.什么是包装类 基本数据类型所对应的引用数据类型 二.集合中不能存储基本数据类型 三.JDK5以后对包装类新增了什么特性? // 自动装箱:把基本数据类型会自动的变成对应的包装类 // 自动拆箱:把包装类自动的变成其对象的基本数据类型 四.我们以后如何获取包…

02-MybatisPlus批量插入性能够吗?

1 前言 “不要用 mybatis-plus 的批量插入,它其实也是遍历插入,性能很差的”。真的吗?他们的立场如下: 遍历插入,反复创建。这是一个重量级操作,所以性能差。这里不用看源码也知道,因为这个和…

【WPF】中的ListBox的ScrollIntoView方法使用

在WPF中,ListBox控件的ScrollIntoView方法用于确保指定的项在可视区域内可见。如果该项不在当前的视图中,该方法会滚动列表,使该项出现在视图中。这对于在用户交互或程序逻辑中需要突出显示特定列表项的场景非常有用。但是不会指定滚动的对齐…

数据结构:手撕代码——顺序表

目录 1.线性表 2.顺序表 2.1顺序表的概念 2.2动态顺序表实现 2.2-1 动态顺序表实现思路 2.2-2 动态顺序表的初始化 2.2-3动态顺序表的插入 检查空间 尾插 头插 中间插入 2.2-4 动态顺序表的删除 尾删 头删 中间删除 2.2. 5 动态顺序表查找与打印、销毁 查找 …

mysql导入sql文件失败及解决措施

1.报错找不到表 1.1 原因 表格创建失败,编码问题mysql8相较于mysql5出现了新的编码集 1.2解决办法: 使用vscode打开sql文件ctrlh,批量替换,替换到你所安装mysql支持的编码集。 2.timestmp没有设置默认值 Error occured at:20…

一个公用的数据状态修改组件

灵感来自于一项重复的工作,下图中,这类禁用启用、审核通过不通过、设计成是什么状态否什么状态的场景很多。每一个都需要单独提供接口。重复工作还蛮大的。于是,基于该组件类捕获组件跳转写了这款通用接口。省时省力。 代码如下:…

Git教程II

介绍一些学习工作中会使用到的git指令。 从远程得到一个指定分支 在clone之后,一般来说本地只会有一个main分支。如果想要获得dev分支该怎么办呢?假设远程的名字是origin,那么可以用git checkout -b dev origin/dev在本地增加dev分支并直接…

Linux开机自启/etc/init.d和/etc/rc.d/rc.local

文章目录 /etc/init.d和/etc/rc.d/rc.local的区别/etc/init.dsystemd介绍 /etc/init.d和/etc/rc.d/rc.local的区别 目的不同: /etc/rc.d/rc.local:用于在系统启动后执行用户自定义命令,适合简单的启动任务。 /etc/init.d:用于管理…