《JVM第8课》垃圾回收算法

文章目录

    • 1.标记算法
      • 1.1 引用计数法
      • 1.2 可达性分析法
    • 2.回收算法
      • 2.1 标记-清除算法(Mark-Sweep)
      • 2.2 复制算法(Coping)
      • 2.3 标记-整理算法(Mark-Compact)
    • 3.三种垃圾回收算法的对比

为什么要进行垃圾回收?

垃圾是指 JVM 中没有任何引用指向它的对象,如果不及时清理这些垃圾对象,那么它就会一直占用内存,如果垃圾对象越来越多,就会出现OOM了。

要判断对象是否是垃圾对象有两种方式,一、引用计数法。二、可达性分析法。

而要清除垃圾对象有三种常用方式,一、标记-清除算法。二、复制算法。三、标记-整理算法。

1.标记算法

要清除垃圾首先要找到垃圾,JVM是通过什么算法找到堆中的垃圾对象的呢?

1.1 引用计数法

每个对象都保存一个引用计数器属性,用于记录对象被引用的次数。如果计数器为 0 则表示是垃圾对象。

优点:原理简单,计数器为 0 则表示是垃圾对象。

缺点

  1. 需要额外的空间和时间来维护引用计数。
  2. (严重) 无法处理循环引用的问题。

循环引用就是A对象里有个B对象的属性,B对象里有个A对象的属性,这样的话A和B的引用计数器都会等于1,永远不会被回收。所以引用计数法很少使用!!!

1.2 可达性分析法

可达性分析法会以GC Roots作为起始点,然后一层一层的去寻找引用的对象,被找到的对象就是存活对象,无法到达的对象就是垃圾对象。

在这里插入图片描述

GC Roots是一组引用,基本常用的包括:

  • 线程的虚拟机栈的栈帧中的方法参数、局部变量所对应的对象引用
  • 线程的本地方法栈的栈帧中的方法参数、局部变量所对应的对象引用
  • 方法区中保存的类信息中静态属性、常量属性所对应的对象引用

2.回收算法

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

既然我们已经能够找到哪些是垃圾对象,那么我们该怎么去回收这些垃圾对象呢?这里又涉及到一些算法,首先比较简单的就是标记-清除算法。

标记-清除算法是一种非常基础的垃圾回收算法,针对某块内存空间,比如新生代、老年代,如果可用内存不足后,就会STW(暂停用户线程的执行),然后执行算法进行垃圾回收:

  1. 标记阶段:从 GC Roots 开始遍历,找到可达对象,并在对象头中进行记录。
  2. 清除阶段:堆内存空间进行线性遍历,如果发现对象头中没有记录是可达对象,则回收它。

在这里插入图片描述

缺点:

  1. 效率不高,和后面讲的算法来比效率确实不高。
  2. 内存碎片,对象被清除后会留下一块一块的小内存,由于这些小内存不是连续的,所以很可能不够存储新来的大对象。

优点:

  1. 思路简单。

2.2 复制算法(Coping)

复制算法的思想就是空间换时间。它将内存空间分为两块,每次只使用一块,在进行垃圾回收时,会首先STW,然后遍历将可达对象复制到另外没有被使用的内存块中,然后再将当前内存块标记为可重用,后续再按相同的流程进行垃圾回收,两块内存交换着来。这也是为什么新生代中会有 S1 和 S2 两块内存区域的原因。

在这里插入图片描述

复制算法只遍历一次,在遍历的同时就把可达对象复制到另一块内存中,而标记-清除算法需要遍历两次,标记和清除各一次。

优点:

  1. 只遍历一次,效率高。
  2. 不会出现内存碎片。

缺点:

  1. 需要更多的内存,始终有一半的空闲内存。
  2. 对象复制后,对象的内存地址发生了变化,需要额外的时间修改栈帧中记录的引用地址。
  3. 如果可达对象比较多,垃圾对象比较少,那么复制算法的效率就会比较低,所以新生代特别适合复制算法,因为新生代的垃圾对象比较多(但也不绝对)。

2.3 标记-整理算法(Mark-Compact)

第一阶段和标记-清除算法一致,也是标记可达对象,也会STW。

第二阶段将所有存活对象移动到内存的一端。

最后清理边界外的所有空间

在这里插入图片描述

优点:

  1. 不会出现内存碎片。
  2. 也不需要利用额外的内存空间。

缺点:

  1. 效率要低于标记清除算法、复制算法。
  2. 也需要修改栈帧中的引用地址。

3.三种垃圾回收算法的对比

标记-清除标记-整理复制
速度中等最慢最快
空间开销少(有碎片)少(无碎片)最多
移动对象

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

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

相关文章

编程之路:蓝桥杯备赛指南

文章目录 一、蓝桥杯的起源与发展二、比赛的目的与意义三、比赛内容与形式四、比赛前的准备五、获奖与激励六、蓝桥杯的影响力七、蓝桥杯比赛注意事项详解使用Dev-C的注意事项 一、蓝桥杯的起源与发展 蓝桥杯全国软件和信息技术专业人才大赛,简称蓝桥杯&#xff0c…

全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现

全网最适合入门的面向对象编程教程:58 Python 字符串与序列化-序列化 Web 对象的定义与实现 摘要: 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML\YAML\JSON格式这种序列化Web对象。这种序列化W…

使用YOLO 模型进行线程安全推理

使用YOLO 模型进行线程安全推理 一、了解Python 线程二、共享模型实例的危险2.1 非线程安全示例:单个模型实例2.2 非线程安全示例:多个模型实例 三、线程安全推理3.1 线程安全示例 四、总结4.1 在Python 中运行多线程YOLO 模型推理的最佳实践是什么&…

每日一题|3255. 长度为 K 的子数组的能量值 II|递增序列、计数器

同昨天的解法一样,遍历一遍的同时,统计当前最长的子串长度,如果>k,则将子串开始位置处赋值子串当前位置元素的值。 class Solution:def resultsArray(self, nums: List[int], k: int) -> List[int]:res [-1] * (len(nums)…

金华迪加现场大屏互动系统 mobile.do.php 任意文件上传漏洞复现

0x01 产品描述: ‌ 金华迪加现场大屏互动系统‌是由金华迪加网络科技有限公司开发的一款专注于增强活动现场互动性的系统。该系统设计用于提供高质量的现场互动体验,支持各种大型活动,如企业年会、产品发布会、展览展示等。其主要功能包…

【网络面试篇】HTTP(1)(笔记)——状态码、字段、GET、POST、缓存

目录 一、相关问题 1. HTTP请求常见的状态码和字段? (1)状态码 (2)字段 ① Host 字段 ② Content-length 字段 ③ Connection 字段 ④ Content-Type 字段 ⑤ Content-Encoding 字段 2. GET 和 POST 的区别&a…

Java学习Day60:微服务总结!(有经处无火,无火处无经)

1、技术版本 jdk&#xff1a;17及以上 -如果JDK8 springboot&#xff1a;3.1及其以上 -版本2.x springFramWork&#xff1a;6.0及其以上 -版本5.x springCloud&#xff1a;2022.0.5 -版本格林威治或者休斯顿 2、模拟springcloud 父模块指定父pom <parent><…

ThreadX在STM32上的移植:F1,F4通用启动文件tx_initialize_low_level.s

在嵌入式系统开发中&#xff0c;实时操作系统&#xff08;RTOS&#xff09;的选择对于系统性能和稳定性至关重要。ThreadX是一种广泛使用的RTOS&#xff0c;它以其小巧、快速和可靠而闻名。在本文中&#xff0c;我们将探讨如何将ThreadX移植到STM32微控制器上&#xff0c;特别是…

UE5.4 PCG基础节点

Projection&#xff1a;投影。可以让撒点重新恢复到表面采样器的初始高度和旋转值。缩放保持不变 DensityFilter&#xff1a;密度过滤器 AttributeNoise&#xff1a;Attribute噪声 模式&#xff1a;设置。重新定义噪点分布为0-1 模式&#xff1a;加0或乘1的时候&#xff0…

STM32-PWR低功耗

一、概述 PWR&#xff08;Power Control&#xff09;电源控制&#xff0c;PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能可编程电压监测&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上…

AI 证件照工具 HivisionIDPhotos

如何在 Linux 系统使用 Docker 在本地部署 HivisionIDPhotos&#xff0c;并结合路由侠内网穿透外网访问本地部署的 HivisionIDPhotos 。 第一步&#xff0c;本地部署安装 HivisionIDPhotos 1&#xff0c;检查 Docker 服务状态&#xff0c;确保 Docker 正常运行。 systemctl …

springboot - 定时任务

定时任务是企业级应用中的常见操作 定时任务是企业级开发中必不可少的组成部分&#xff0c;诸如长周期业务数据的计算&#xff0c;例如年度报表&#xff0c;诸如系统脏数据的处理&#xff0c;再比如系统性能监控报告&#xff0c;还有抢购类活动的商品上架&#xff0c;这些都离不…

pandas——对齐运算+函数应用

引言&#xff1a;对齐运算是数据清洗的重要过程&#xff0c;可以按索引对齐进行运算&#xff0c;如果没对齐的位置则补NaN&#xff0c;最后也可以填充NaN 一、Series的对齐运算 1.Series 按行、索引对齐 import pandas as pds1 pd.Series(range(10, 20), indexrange(10)) s2…

画动态爱心(Python-matplotlib)

介绍 氵而已 由于用的是 AI&#xff0c;注释得非常清楚&#xff0c;自己改改也可以用 代码 # -*- coding: utf-8 -*- # Environment PyCharm # File_name 尝试1 |User Pfolg # 2024/11/05 22:45 import numpy as np import matplotlib.pyplot as plt import matplot…

学习threejs,将多个网格合并成一个网格

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.Geometry 几何体1.2 …

对于一个需要渲染300帧的动画项目,云渲染要多久

探讨云渲染动画300帧需要多久的问题时&#xff0c;我们今天来从多个角度进行分析&#xff0c;对于一个需要渲染300帧的动画项目&#xff0c;传统的本地渲染方式可能会因为硬件限制而变得耗时且效率低下。幸运的是&#xff0c;【渲染101】云渲染技术的出现为这一问题提供了解决方…

系统上云-流量分析和链路分析

优质博文&#xff1a;IT-BLOG-CN 一、流量分析 【1】流量组成&#xff1a; 按协议划分&#xff0c;流量链路可分为HTTP、SOTP、QUIC三类。 HTTPSOTPQUIC场景所有HTTP请求&#xff0c;无固定场景国内外APP等海外APP端链路选择DNS/CDN(当前特指Akamai)APP端保底IP列表/动态IP下…

「Mac畅玩鸿蒙与硬件22」鸿蒙UI组件篇12 - Canvas 组件的动态进阶应用

在鸿蒙应用中&#xff0c;Canvas 组件可以实现丰富的动态效果&#xff0c;适合用于动画和实时更新的场景。本篇将介绍如何在 Canvas 中实现动画循环、动态进度条、旋转和缩放动画&#xff0c;以及性能优化策略。 关键词 Canvas 组件动态绘制动画效果动态进度条旋转和缩放性能优…

C 学习(4)

return 0; 前提&#xff1a;C 语言规定&#xff0c;main()是程序的入口函数&#xff0c;即所有的程序一定要包含一个main()函数。程序总是从这个函数开始执行&#xff0c;如果没有该函数&#xff0c;程序就无法启动。其他函数都是通过它引入程序的。 main()的写法&#xff0c…

Springboot3.3 + Mybatis / Mybatis-plus

Java17, Springboot 3.3.5, 项目一启动就报错&#xff1a; Invalid value type for attribute factoryBeanObjectType: java.lang.String 我知道问题出现在pom依赖的版本上。但网上对于Springboot3.3的配置资料并不多&#xff0c;且在我代码上实测还是会报错。搞了一天终于…