JVM(Java Virtual Machine)垃圾收集算法篇

news2025/1/15 22:45:06

前言

本文参考《深入理解Java虚拟机》,主要介绍GC相关的算法,引用计数法、可达性分析算法、垃圾收集算法(分代收集理论,标记-清除/整理/复制)

本系列其他文章链接:
JVM(Java Virtual Machine)垃圾收集算法篇

垃圾收集

当对象不在被使用的时候,就被当做垃圾给GC掉以节省内存空间,而大部分GC都发生在堆内存中,因为这个区域是所有Java线程共享的,最容易OOM的地方

引用计数算法

概念

引用计数算法:在对象中添加一个引用计数器,每当有一个地方引用它的时候,计数器值加一;当一个引用失效的时候,计数器值就减一;任何时刻计数器为0的对象就是不可能再被使用的。

存在问题

在特定情况下,这个效率还是比较高的算法,但是还是会有限问题存在:相互引用导致无法被回收即使他们不在被使用了,如下图示:
在这里插入图片描述
图中,对象56,当他们互相引用,但是却没有人使用他们之中任意一个,使用计数器计数,他们的值永远不为0,就不会被回收,导致内存泄漏的问题。所以,在单独使用计数器是没有办法解决垃圾回收标记问题的。

可达性分析算法

概念

这个算法的基本思路就是通过一系列称为:“GC Roots”的根对象作为起始点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”,如果某个对象到GC Roots间没有任何引用链相连,则说明这个对象不可达,证明此对象不可能再被使用的。如下图所示:在这里插入图片描述

GC Roots对象包括哪些

在Java技术体系,固定可作为GC Roots的对象包括以下几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 在方法区类静态属性常量引用的对象
  • 本地方法栈中JNI引用对象
  • Java虚拟机内部的引用
  • 所以被同步锁持有的对象

引用

无论是引用计数器还是可达性分析,判断对象的存活都和“引用”离不开关系。

在JDK1.2之前,Java里面的引用是很传统的定义:如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称该reference数据是代表某块内存、某个对象的引用。

在JDK1.2之后,Java对引用的概念进行了扩充,将引用分为“强/软/弱/虚引用”,这四种引用强度依次减弱

  • 强引用:这是最传统的,引用赋值,Object o = new Object();
  • 软引用:用来描述一些还有用,但非必要对象,这类对象将在第二次GC被回收,JDK1.2提供了SoftReference实现软引用;
  • 弱引用:用来描述非必须对象,比软引用更弱,第一次GC就会被回收,WeakReference实现弱引用;
  • 虚引用:最弱的一种引用关系。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收收到一个系统通知。PhantomReference类来实现虚引用;

垃圾收集算法

分代收集理论

大多数垃圾收集器都基于“分代收集理论”进行设计,这套理论实际上是一套符合大多数程序运行实际情况的经验法则,它建立在两个假说之上

  • 弱分代假说:绝大多数对象都是朝生夕死;(新生代区域)
  • 强分代假说:熬过越多次垃圾收集过程的对象就越难以消亡;(老年代区域)

依据这个理论,收集器将Java堆划分不同的区域。一个区域放置朝生夕死的对象,一个区域放置熬过多次垃圾收集还“活着”的对象。

对于不同的区域(新生代、老年代),则根据不同的区域使用不同的垃圾收集算法,因此有了“Minor GC”、“Major GC”、“Full GC”,

标记-清除算法

标记-清除算法:首先标记出所需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,或者反过来。这个算法效率是它的优点,因为标记完,回收掉就可以了,不需要其他操作,所有这也成了最大的缺点,容易出现内存碎片,如下图:
在这里插入图片描述
产生大量不连续的内存碎片,可能会导致分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

标记-复制算法

标记-复制算法的底层思想是“半区复制”,它将内存按容量划分大小相等的两块,每次只使用其中一块,当这一块的内存用完了,就将存活的对象复制到另一块上,然后把使用过的那一块清空,等待下一次交换使用。

这样的垃圾收集过程中就只需移动指针位置即可,不会存在内存碎片的问题,实现简单,运行高效,但是这样有一个比较大的问题,内存始终都是有一块在某种意义上是浪费的。

但是为我们所知道的,对象大部分都是朝生夕死的,98%的对象都熬不过第一次垃圾回收,所以并不需要1:1比例来划分新生代的内存空间。在HotSpot虚拟机中,默认分配比例大小是Eden:Survivor(from:to) == 8:1:1,也就是说每次内存分配只使用Eden和Survivor的另一块。

情况如下图所示:
在这里插入图片描述

标记-整理算法

标记-复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。

标记-整理算法就是让所有存活的对象向一端移动,然后清理掉边界以外的内存。

标记-清除算法与标记-整理算法的本质差异在于前者是一种非移动式的回收算法,后者是移动式的。

END
希望以上内容能给你提供帮助

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

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

相关文章

视频监控/安防监控平台EasyCVR新功能——视频播放id调阅来咯

TSINGSEE青犀视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&…

中小型企业云存储选型指南:要点与建议

随着信息技术的快速发展,中小型企业越来越依赖于云存储来管理和存储其日益增长的数据。选择适合自己企业的云存储解决方案是确保数据安全、提高工作效率的关键。 选型注意点: 选择适合自己企业的云存储方案 在选择适合自己企业的云存储方案时&#xff…

日志回滚工作原理剖析及在文件系统的作用

日志回滚原理 当涉及到崩溃恢复和一致性保护时,日志回滚是一种常见的机制。它通过记录写入操作到一个事务日志中,而不是直接应用到文件系统,以保护文件系统的一致性。下面是日志回滚的一般工作原理: 日志记录:在进行写…

【COMP305 LEC 1 2】

Part 1 Artificial Neural Networks(ANN) Topic 1 Historical/Biological Introduction 1. Biological Excitability (a. Virtually all living cells maintain an electrical potential difference between their interiors and the environment (exteriors) . 内部和外…

1812_参考spacemacs的文档拆解ivy layer的组成

全部学习汇总: GreyZhang/editors_skills: Summary for some common editor skills I used. (github.com) 升级了spacemacs的配置,之后重新翻了一下spacemacs的文档。看到了这里面的一个核心的结构layer。这样,结合文档并且找出一个layer来看…

【多线程】线程安全问题和解决方案

我们来看下面这一段代码 public class demo {public static void main(String[] args) throws InterruptedException {Cou count new Cou();Thread t1 new Thread(() -> {for (int i 0; i < 10000; i) {count.add();}});Thread t2 new Thread(() -> {for (int i …

王道计算机考研 操作系统学习笔记篇章二: 进程管理

目录 进程与线程 进程的概念 概念 进程的组成 PCB 程序段、数据段 进程的特征 总结 进程的状态与转换 进程的状态 创建态、就绪态 运行态 阻塞态 终止态 进程的转换 进程的组织 链接方式 索引方式 总结 进程控制 什么是进程控制 如何实现进程控制 进程控制相关的原…

Opencv之RANSAC算法用于直线拟合及特征点集匹配详解

Opencv之RANSAC算法用于直线拟合及特征点集匹配详解 讲述Ransac拟合与最小二乘在曲线拟合上的优缺点 讲述在进行特征点匹配时&#xff0c;最近邻匹配与Ransac匹配的不同之处 另外&#xff0c;Ransac也被用于椭圆拟合、变换矩阵求解等 1. 直线拟合 1.1 原理 RANSAC(RANdom …

两分钟搞懂UiAutomator自动化测试框架

1. UiAutomator简介 UiAutomator是谷歌在Android4.1版本发布时推出的一款用Java编写的UI测试框架&#xff0c;基于Accessibility服务。其最大的特点就是可以跨进程操作&#xff0c;可以使用UiAutomator框架提供的一些方便的API来对安卓应用进行一系列的自动化测试操作&#xf…

Linux程序调试器——gdb的使用

gdb的概述 GDB 全称“GNU symbolic debugger”&#xff0c;从名称上不难看出&#xff0c;它诞生于 GNU 计划&#xff08;同时诞生的还有 GCC、Emacs 等&#xff09;&#xff0c;是 Linux 下常用的程序调试器。发展至今&#xff0c;GDB 已经迭代了诸多个版本&#xff0c;当下的…

C#上位机序列9: 批量读写+事件广播+数据类型处理

一、源码结构&#xff1a; 二、运行效果&#xff1a; 三、源码解析 1. 读取配置文件及创建变量信息&#xff08;点位名称&#xff0c;地址&#xff0c;数据类型&#xff08;bool/short/int/float/long/double&#xff09;&#xff09; 2. 异步任务处理&#xff1a;读任务&…

c++_learning-并发与多线程

并发与多线程 并发&#xff1a;进程&#xff1a;线程&#xff1a;基本概念&#xff1a;线程安全&#xff1a;问题出现的场景&#xff1a;涉及的性质&#xff1a;如何保证线程安全&#xff1f; 并发的实现手段&#xff08;优先使用多线程并发&#xff09;&#xff1a;多进程并发…

【特征重要性揭秘:为什么同一个数据集会有不同结果】

文章目录 特征重要性概要为什么特征重要性分析很重要特征重要性分析方法内置特征重要性(coef_或feature_importances_)Leave-one-out相关性分析递归特征消除 Recursive Feature EliminationXGBoost特性重要性主成分分析 PCA方差分析 ANOVA卡方检验&#xff08;Chi-Square Test&…

求最大公约数的几种常见的方法 【详解】

目录 一、关于公约数 二、计算最大公约数的方法 1. 辗转相除法&#xff08;欧几里得算法&#xff09; 2. 更相减损法&#xff08;辗转相减法&#xff09; 3. 分解质因数法 4. 穷举法 5. 递归法 6. 短除法 三、总结 一、关于公约数 首先 &#xff0c;先介绍一下公约…

matplotlib python 画图教程(2)

1、bar 柱状图 import matplotlib.pyplot as plt import numpy as np n12 xnp.arange(12) y1(1-x/float(n))*np.random.uniform(0.5,1,n) y2(1-x/float(n))*np.random.uniform(0.5,1,n) plt.xlim(-.5,n) plt.ylim(-1.25,1.25) plt.xticks([]) plt.yticks([]) plt.bar(x,y1,fac…

利用TypeScript 和 jsdom 库实现自动化抓取数据

以下是一个使用 TypeScript 和 jsdom 库的下载器程序&#xff0c;用于下载zhihu的内容。此程序使用了 duoip.cn/get_proxy 这段代码。 import { JSDOM } from jsdom; import { getProxy } from https://www.duoip.cn/get_proxy;const zhihuUrl https://www.zhihu.com;(async (…

01、Python 安装 ,Pycharm 安装

目录 安装安装 Python安装 Pycharm 创建项目简单添加文件运行 简单爬取下载小视频 安装 python-3.8.10-amd64.exe – 先安装这个 pycharm-community-2022.2.exe 再安装这个 安装 Python python-3.8.10-amd64.exe 安装&#xff08;这个是其他版本的安装&#xff0c;步骤一样…

Linux安装MINIO

MINIO简介MINIO目录 mkdir -p /opt/minio/data && cd /opt/minio MINIO下载 wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio MINIO授权 chmod x minio MINIO端口 firewall-cmd --zonepublic --add-port7171/tcp --permanent && firewal…

RTOS(6)任务管理

任务状态理论 我们是怎么实现&#xff0c;两个同优先级的任务之间交替执行的呢&#xff1f; 任务切换的基础&#xff1a;tick中断&#xff01; tick为1ms一个周期&#xff0c;可以通过修改时钟配置修改&#xff1b; running&#xff1a;正在进行的任务3为running&#xff…

20231019 filezilla 配置 Windows与Ubuntu文件传输

SFTP协议&#xff0c;传文件&#xff0c;否则会报无权限错