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

【JVM】垃圾收集算法

文章目录

  • 分代收集理论
  • 标记-清除算法
  • 标记-复制算法
  • 标记-整理算法

分代收集理论

当前商业虚拟机的垃圾收集器,大多数都遵循了“分代收集”(Generational Collection)[1]的理论进 行设计,分代收集名为理论,实质是一套符合大多数程序运行实际情况的经验法则,它建立在两个分代假说之上:

  1. 弱分代假说(Weak Generational Hypothesis):绝大多数对象都是朝生夕灭的。

  2. 强分代假说(Strong Generational Hypothesis):熬过越多次垃圾收集过程的对象就越难以消 亡。

把分代收集理论具体放到现在的商用Java虚拟机里,设计者一般至少会把Java堆划分为新生代 (Young Generation)和老年代(Old Generation)两个区域[2]。顾名思义,在新生代中,每次垃圾收集 时都发现有大批对象死去,而每次回收后存活的少量对象,将会逐步晋升到老年代中存放。

对于分代理论,由于会存在老年代引用新生代的情况,这对于回收对象时的判断会造成性能影响,所以还应该有下面假说

  1. 跨代引用假说(Intergenerational Reference Hypothesis):跨代引用相对于同代引用来说仅占极少数。

上面条结论可根据前两条假说逻辑推理得出的隐含推论:存在互相引用关系的两个对象,是应该倾向于同时生存或者同时消亡的。

下面是一些常见的分代收集名词

  • 部分收集(Partial GC):指目标不是完整收集整个Java堆的垃圾收集,其中又分为:

    • 新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集。

    • 老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集。目前只有CMS收集器会有单独收集老年代的行为。

    • 混合收集(Mixed GC):指目标是收集整个新生代以及部分老年代的垃圾收集。目前只有G1收集器会有这种行为。

  • 整堆收集(Full GC):收集整个Java堆和方法区的垃圾收集。

标记-清除算法

标记-清除算法(Mark and Sweep Algorithm)是一种经典的垃圾回收算法,用于识别和释放不再被引用的对象,从而回收内存空间。它包括两个主要阶段:标记(Mark)和清除(Sweep)。

下面是标记-清除算法的工作原理:

  1. 标记(Mark)阶段
    • 从根对象(通常是程序的入口点或全局变量)开始,遍历整个对象图,标记所有可以从根对象访问到的对象。
    • 在这个阶段,被标记的对象通常被打上一个标记位或者加入一个"已标记"的集合中,以表示它们是活跃对象,仍然被引用。
  2. 清除(Sweep)阶段
    • 在清除阶段,垃圾回收器遍历整个堆内存,找到所有未被标记的对象,这些对象是不再被引用的对象。
    • 未被标记的对象被认为是垃圾,垃圾回收器会将它们的内存空间标记为可用空闲空间,以供将来的对象分配使用。
    • 清除后,堆内存中只剩下被标记的对象,而未被标记的对象的内存已经被释放。

上面有一点需要注意的是,标记对象可以是所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。

下面是标记-清除算法的示意图

image-20230904194201368

标记-清除算法的优点是它可以回收不再被引用的对象,但它也有一些缺点:

  • 碎片问题:标记-清除算法会在内存中留下不连续的空闲块,可能导致内存碎片化问题。这会增加分配大对象时的空间不足问题的风险。
  • 效率问题:标记-清除算法需要两次遍历整个堆内存:一次标记,一次清除。这会产生额外的性能开销,尤其是在清除阶段。
  • 停顿问题:标记-清除算法在清除阶段需要停止应用程序的执行,因为它需要整个堆内存处于不变状态才能执行清除操作。这可能导致应用程序在垃圾回收期间出现停顿,影响用户体验。

标记-复制算法

标记-复制算法(Mark and Copy Algorithm)是一种用于垃圾回收的算法,它解决了标记-清除算法中出现的内存碎片问题。标记-复制算法主要用于新生代(Young Generation)的垃圾回收,通常分为两个阶段:标记(Mark)和复制(Copy)。

下面是标记-复制算法的工作原理:

  1. 标记(Mark)阶段

    • 从根对象(通常是程序的入口点或全局变量)开始,遍历整个对象图,标记所有可以从根对象访问到的对象,这些对象被认为是活跃对象。
    • 在这个阶段,被标记的对象通常被打上一个标记位或者加入一个"已标记"的集合中,以表示它们是活跃对象,仍然被引用。
  2. 复制(Copy)阶段

    • 在复制阶段,垃圾回收器会将所有被标记为活跃对象的对象从一个区域(通常称为"From"或"Eden"区)复制到另一个区域(通常称为"To"或"Survivor"区)。
    • 复制后,所有被复制的对象都连续排列在一起,没有碎片,而"From"区变成了空的。
  3. 清理(Clean-Up)阶段

    • 清理阶段不再需要被复制的对象,因此整个"From"区可以被清空,成为新的可用空间,用于将来的对象分配。

示意图如下

image-20230904195708455

标记-复制算法的主要优点是它有效地解决了内存碎片问题。因为被复制的对象都被整齐地排列在一起,"From"区变为空,所以不会出现内存碎片化的情况。这提高了内存的利用率,减少了分配大对象时可能出现的空间不足问题。缺点就是比较浪费空间。

标记-复制算法主要用于新生代的垃圾回收,而老年代通常使用其他算法,如标记-清除或标记-整理算法。这些不同的垃圾回收算法结合在一起,构成了现代Java虚拟机中的复杂垃圾回收策略,以提高内存管理的效率和性能。

标记-整理算法

标记-整理算法(Mark and Compact Algorithm)是一种用于垃圾回收的算法,通常用于老年代(Old Generation)的内存回收。它是标记-清除算法的改进版本,主要解决了标记-清除算法可能导致的内存碎片问题。

相较于标记-清楚算法只是多了一个整理的过程

整理(Compact)阶段

  • 在整理阶段,垃圾回收器会将所有被标记为活跃对象的对象向一端移动,以便它们连续排列在一起。同时,未被标记/被标记的对象都被认为是垃圾,不再需要,它们的内存空间会被释放。
  • 整理后,内存中的活跃对象变得更加紧凑,没有碎片,可以提高内存的利用率。

示意图如下

image-20230904200134998

相关文章:

【JVM】垃圾收集算法

文章目录 分代收集理论标记-清除算法标记-复制算法标记-整理算法 分代收集理论 当前商业虚拟机的垃圾收集器,大多数都遵循了“分代收集”(Generational Collection)[1]的理论进 行设计,分代收集名为理论,实质是一套符…...

K8s的Pod出现Init:ImagePullBackOff问题的解决(以calico为例)

对于这类问题的解决思路应该都差不多,本文以calico插件安装为例,发现有个Pod的镜像没有pull成功 第一步:查看这个pod的描述信息 kubectl describe pod calico-node-wmhrw -n kube-system 从上图发现是docker拉取"calico/cni:v3.15.1&q…...

数据结构 -作用及基本概念

为什么要使用数据结构 学习数据结构是计算机科学和软件工程领域中非常重要的一门课程。以下是学习数据结构的几个重要原因: 组织和管理数据:数据结构提供了一种组织和管理数据的方式。通过学习不同的数据结构,你可以了解如何有效地存储和操作…...

数学建模--时间序列预测模型的七种经典算法的Python实现

目录 1.开篇版权提示 2.时间序列介绍 3.项目数据处理 4.项目数据划分可视化 5.时间预测序列经典算法1:朴素法 6.时间预测序列经典算法2: 简单平均法 7.时间预测序列经典算法3:移动平均法 8.时间预测序列经典算法4:简单指…...

nginx-反向代理缓存

反向代理缓存相当于自动化动静分离。 将上游服务器的资源缓存到nginx本地,当下次再有相同的资源请求时,直接讲nginx缓存的资源返回给客户端。 本地缓存资源有一个过期时间,当超过过期时间,则重新向上游服务器重新请求获取资源。…...

大模型重塑区域人才培养,飞桨(重庆)人工智能教育创新中心正式启动

2023年8月22日,重庆市高校人工智能产教融合院长研讨会暨飞桨(重庆)人工智能教育创新中心启动仪式在重庆大学成功召开。会上,由百度飞桨、重庆大学组织重庆市二十一所高校共建的飞桨(重庆)人工智能教育创新中…...

PAT 1164 Good in C 测试点3,4

个人学习记录,代码难免不尽人意。 When your interviewer asks you to write “Hello World” using C, can you do as the following figure shows? Input Specification: Each input file contains one test case. For each case, the first part gives the 26 …...

LabVIEW对EAST长脉冲等离子体运行的陀螺稳态运行控制

LabVIEW对EAST长脉冲等离子体运行的陀螺稳态运行控制 托卡马克是实现磁约束核聚变最有希望的解决方案之一。电子回旋共振加热(ECRH是一种对托卡马克有吸引力的等离子体加热方法,具有耦合效率高,功率沉积定位好等优点。陀螺加速器是ECRH系统中…...

Fragment

Fragment是Android开发中的一个重要组件,用于构建灵活且可重用的用户界面模块。它可以作为Activity的一部分来展示用户界面,并且可以嵌套在其他Fragment中,从而形成复杂的界面层级。 以下是一个简单的示例,展示了如何在Android中…...

哈希表-救赎金

Leetcode: https://leetcode.cn/problems/ransom-note/?envTypestudy-plan-v2&envIdtop-interview-150 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true …...

vue3+vite+ts项目适配各种分辨率解决方案

现在的电脑屏幕和尺寸越来越多样化,对于前端开发来说,适配各种屏幕成了大难题,开发中一个实际例子:开发一个导航栏,ui给的是1920*60的尺寸,前端开发的时候,在自己电脑缩放比例中开发的&#xff…...

Python Opencv实践 - 矩形轮廓绘制(直边矩形,最小外接矩形)

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/stars.png") plt.imshow(img[:,:,::-1])img_gray cv.cvtColor(img, cv.COLOR_BGR2GRAY) #通过cv.threshold转换为二值图 ret,thresh cv.threshold(img_gray,…...

大数据HBASE的详细使用

摘要:本文将深入探讨大数据HBASE的使用步骤,帮助读者了解和掌握这一强大的分布式数据库系统的基本概念和操作技巧。通过本文的阅读,读者将能够熟悉HBASE的基本设置,了解其核心概念,掌握基本的查询和管理操作&#xff0…...

Sentinel 流量控制框架

1. Sentinel 是什么? Sentinel是由阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件。 2. 主要优势和特性 轻量级,核心库无多余依赖,性能损耗小。 方便接入,开源生态广泛。 丰富的流量控制场景。 …...

leetcode原题: 跳水板

题目: 你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。你必须正好使用k块木板。编写一个方法,生成跳水板所有可能的长度。 返回的长度需要从小到大排列。 示例&…...

深度学习入门(Python)学习笔记1

第1章 Python入门 1.1python是什么 Python是一个简单、易读、易记的编程语言,而且是开源的,可以免费地自由使用。 使用Python不仅可以写出可读性高的代码,还可以写出性能高(处理速度快)的代码。 再者,在…...

苏州想要获得融资融券低利率账户的方法?怎么开融资融券账户?

想要获得融资融券低利率账户,可以通过以下几种方式: 选择低费率的券商:不同券商的费率不同,一些券商会提供低利率的融资融券账户,可以通过咨询券商或者比较不同券商的费率来找到最佳账户。 提升自身信用:获…...

【LeetCode周赛】LeetCode第359场周赛

LeetCode第359场周赛 判别首字母缩略词k-avoiding 数组的最小总和销售利润最大化找出最长等值子数组 判别首字母缩略词 给你一个字符串数组 words 和一个字符串 s ,请你判断 s 是不是 words 的 首字母缩略词 。 如果可以按顺序串联 words 中每个字符串的第一个字符…...

vue3+ts+tinynce在富文本编辑器菜单栏实现下拉框选择

实现效果 代码&#xff1a; <script lang"ts" setup> import Editor from tinymce/tinymce-vue import tinymce from tinymce; import { getIndicator } from /api/data-assets/data-dictoryimport {computed, ref} from "vue"; const props defin…...

前端UI组件库深度解析:构建现代化的用户体验

引言 在当今的前端开发中&#xff0c;UI组件库已经成为了我们工具箱中不可或缺的一部分。这些库可以极大地提高我们的工作效率&#xff0c;同时也使我们能够专注于实现真正的业务逻辑&#xff0c;而不是重复地编写UI代码。本篇博客将详细地探讨UI组件库的核心概念&#xff0c;…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...