JVM原理及其机制(二)

目录

一 . 垃圾回收机制(GC)

二 . 垃圾回收的具体步骤 

(1)先找出谁是垃圾 

方案一:引用计数

方案二:可达性分析

(2)释放垃圾的内存空间 

方案一:标记清除

方案二:复制算法

方案三:标记 — 整理

方案四:分代回收算法


一 . 垃圾回收机制(GC)

在我们上一期讲了 Java 在运行时内存的各个区域,对于程序计数器、虚拟机栈、本地方法栈这三个部分区域而言,其生命周期与相关线程有关,随线程而生,随线程而灭。并且这三个区域的内存分配与回收具有确定性,因为当方法结束或线程结束时,内存就自然跟着线程回收了,

什么是垃圾回收机制呢?顾名思义,就是清理掉我们在 Java 堆中用完的、不用的对象实例,垃圾回收器在对堆进行垃圾回收前,首先要判断这些对象哪些还 “ 活着 ”,哪些已经 “ 死去 ” 。

这个垃圾回收机制是很香的,程序员写代码放心大胆的 new ,JVM 会自动识别哪些 new 完的对象再也不用了,就会将其自动释放掉。

像我们主流语言中绝大部分都是内置了 GC 的,例如 GO、Python、PHP、JS ...... 但是我们的C++ 却不支持 GC ,这是为什么呢?

任何功能都是有代价的,C++ 的大佬们评估了风险之后,不愿意承担,所以 C++ 并不支持 GC,其主要原因有:要想在JVM 中引入 GC 机制,就需要额外的逻辑,首先会消耗不少的 CPU 开销,进行垃圾扫描和释放,其次在进行 GC 的时候可能会触发 STW(Stop The World)问题,导致程序卡顿。

二 . 垃圾回收的具体步骤 

(1)先找出谁是垃圾 

需要针对每个对象分别判定是否为 “ 垃圾 ”

方案一:引用计数

给每个对象分配一个计数器,这一计数器用来衡量该对象有多少个引用指向。每增加一个引用,计数器 + 1 ,每减少一个引用,计数器 - 1 ,当计数器减为 0 ,此时该对象就是 “ 垃圾 ” 了。

但是这个方案在实施过程中存在着一些问题,例如会消耗额外的空间。假设我们 Test 类就只有一个 int 成员(4个字节),为了引入引用计数,少说得搞个 short(2字节),内存就多占了 50% 。其次很可能导致 “ 循环引用 ” 使得判定出错,这跟我们之前学过的死锁问题有些相似。循环引用也是有解决方案的,需要引入更多的机制,例如环路检测(在 Python 中就使用的这种机制),但是这样一来,代价就更大了。所以综上所述,Java 并没有采用这种引用计数的方法,而是另一种:

方案二:可达性分析

可达性分析主要就是 “ 用时间换空间 ” ,在 JVM 中,专门搞了一波线程,周期性的去扫描代码中的所有对象,来判定每个对象是否 “ 可达 ”(可以被访问到),对应的,不可达的对象,就会被视为垃圾。

可达性分析的起点称为 GC root ,从 root 出发,尽可能的通过 root 访问到更多的对象,相当于遍历的过程,但严格来说,并不是树的遍历,而是图的遍历。一个程序中,GC root 不是只有一个,而是有很多很多,可以作为 GC root 的对象有三种:栈上的局部变量(引用类型)、方法区中,静态成员变量(引用类型)、常量池引用指向的对象。把所有的 GC root 都遍历一遍,针对每一个尽可能往下延伸。

(2)释放垃圾的内存空间 

方案一:标记清除

标记清除法就是将需要回收的垃圾标记上,然后直接对其进行清理。

标记清除法主要有两大缺陷,首先是效率问题,标记和清除这两个过程效率都不高,其次是空间碎片问题,在清除之后会产生大量不连续的内存碎片,空间碎片太多可能导致以后在程序运行中需要分配较大对象时,就可能申请不了,因为无法找到足够的连续的空间(申请内存一定是需要连续的空间)。尽量避免内存碎片,时释放内存的关键,所以我们又有了第二种方案:

方案二:复制算法

复制算法就是将我们的内存空间一分为二,每次只使用一半,当我们进行垃圾清理的时候,将不是垃圾的对象拷贝到另一半中,并且确保拷贝的这些对象在这一半内存空间中是连续的,然后直接将原本那一半的内存空间全部释放掉。

复制算法的缺点也很明显:首先就是每次只能用一半的内存,内存空间利用率非常低,其次是如果存活下来的对象很多,复制的成本将会非常大。于是我们引入了第三种方案:

方案三:标记 — 整理

标记、整理非常类似与我们之前学习过的顺序表,删除中间元素。当我们需要对垃圾对象进行清理时,依次将还存活的对象往一端移动,将垃圾对象替换掉,最后直接清理掉端边界以外的内存。

这里需要注意的是,这里对于存活对象搬运的开销也不少。所以,综上所述,其实并没有哪一种方案能做到十全十美,在实际开发过程中,我们都是结合运用,取长补短,于是就有了分代回收:

方案四:分代回收算法

JVM 根据对象的 “ 年龄 ” ,将对象进行区分,年轻的我们叫做新生代,年老的我们称作老年代。这种 “ 年龄 ” 是怎样划分的呢?通过我们的可达性分析,周期性的,每次经过一轮的扫描对象仍然存活(不是垃圾),其年龄就 + 1 。

分代回收,是 JVM 的 GC 中的基本思想,当具体落实到 JVM 的实现层面上,JVM 还提供了许多种 “ 垃圾回收器 ” ,这些垃圾回收器在具体实施中就会对分代回收做进一步的扩充和实现,如下:

CMS 的原理同样也是采用分代回收,它的设计理念就是把整个 GC 过程拆分成多个阶段,能和业务线程并发执行就尽量并发,从而尽可能的减少 STW 的耗时:

G1 就是把整个内存分成很多个小块,不同的颜色(字母)就表示这一小块是新生代(伊甸区 / 幸存区)还是老年区。进行 GC 的时候,不要求一个周期就将其中的所有内存都回收一遍,而是一轮 GC 只回收其中的一部分就好,这样就可以很好的限制你一轮 GC 所花的时间,这样就使得 STW 的耗时在一个可控的范围之内。

OKK,咱们有关 JVM 的原理及其相关机制的内容板块就说这么多了,这部分主要就是靠被,这些知识就是靠我们去背八股文这种来记,当然了,大家也需要理解记忆,并不是说硬背啦。就这样吧,咱们下期再见咯,与诸君共勉!!!

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

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

相关文章

Solo:基于 zkHE 的身份验证协议,构建 Web3 可信匿名身份层

“Solo 正在基于其独创的 zkHE 架构,构建一套“可信匿名”的链上身份系统,有望打破长期困扰 Web3 的“不可能三角”,即在隐私保护、身份唯一性与去中心化可验证性之间实现兼得。”前不久,Web3 身份层项目 Solo 宣布完成 120 万美元…

【Excel函数】将数据非空的字段筛选出来放在新列

一、需求描述 将对应数据不为空的字段筛选出来放在新的列里 二、解析 IFERROR(INDEX(B$2:B$10,SMALL(IF(C$2:C$10<>"",ROW(C$2:C$10)-ROW(C$2)1),ROW(A1))),"") 1. IF(C$2:C$10<>"", ROW(C$2:C$10)-ROW(C$2)1) 作用&#xff1a;…

【unity游戏开发入门到精通——组件篇】unity的粒子系统力场 (Particle System Force Field)实现如旋风、吸引力、风吹效果等

文章目录前言一、参数介绍二、Particle System Force Field 的核心特性三、如何使用1、粒子系统开启外力选项2、然后再添加粒子系统力场 (Particle System Force Field)即可参考专栏推荐完结前言 Unity的粒子系统是一个非常强大的工具&#xff0c;可以用来创建各种动态效果&am…

JS逆向基础( AES 解密密文WordArray和Uint8Array实战②)

1. Uint8Array 就像「快递柜」 每个格子固定放「1 瓶饮料」(1 字节 = 8 位,范围 0-255 就像饮料编号) 比如装了 3 瓶:可乐(编号 255)、雪碧(10)、矿泉水(0) 这是超市通用的标准货架,任何工具(JS 内置功能)都认识这种摆放方式 用途:运输、存储所有二进制东西(图片…

论文阅读:《针对多目标优化和应用的 NSGA-II 综述》一些关于优化算法的简介

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

Elasticsearch(ES)安装

docker下安装ES 拉取镜像docker pull elasticsearch:7.4.0 创建文件夹 权限赋值 chmod -R 777 /usr/local/docker/es 创建配置 #可访问IP http.host: 0.0.0.0 # 跨域 http.cors.enabled: true http.cors.allow-origin: "*" 编写脚本并赋权 首先先返回上一级目录&…

Pycharm、Python安装及配置小白教程

本篇博客主要介绍了如何使用工具软件快速安装Pycharm和Python并完成基础配置。 目录 一、Python与Pycharm是什么&#xff1f; 二、安装工具软件 三、安装Python 四、安装Pycharm 五、配置Pycharm 1. 基础设置 2. 配置解释器 一、Python与Pycharm是什么&#xff1f; …

Redis数据库入门教程

Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、基于内存的高性能键值存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。本教程将带你从零开始全面学习Redis&#xff0c;涵盖基础概念、安装配置、数据结构、持久化机制以及与Python的交互等内容…

工业仪表识别(一)环境安装

仪表识别环境安装 &#xff11;&#xff0e;cuda cuda 11.8 intall&#xff08;cuda11.8、cuda12.6按照需求安装&#xff09; ref: https://developer.nvidia.com/cuda-11-8-0-download-archive?target_osLinux&target_archx86_64&DistributionUbuntu&target_vers…

闲庭信步使用图像验证平台加速FPGA的开发:第三十四课——车牌识别的FPGA实现(6)叠加车牌识别的信息

&#xff08;本系列只需要modelsim即可完成数字图像的处理&#xff0c;每个工程都搭建了全自动化的仿真环境&#xff0c;只需要双击top_tb.bat文件就可以完成整个的仿真&#xff0c;大大降低了初学者的门槛&#xff01;&#xff01;&#xff01;&#xff01;如需要该系列的工程…

Windows上用于跨平台开发的环境工具

1. MSYS2&#xff08;Minimal SYStem 2&#xff09; 一款模拟Unix环境的软件&#xff0c;可以执行unix命令。通过pacman管理工具&#xff0c;类似Ubuntu上apt-get&#xff0c;RedHat中的yum。 MSYS2最大好处就是能够在Windows上轻松编译一些由Unix环境工具链开发的工程&#…

【硬件-笔试面试题】硬件/电子工程师,笔试面试题-15,(知识点:DC-DC电源,BUCK电路,铁损,铜损)

目录 1、题目 2、解答 选项 A 选项 B 选项 C 选项 D 3、相关知识点 一、纹波 二、感量&#xff08;电感量L&#xff09; 三、开关频率f 四、铁损 五、铜损 题目汇总版&#xff1a; 【硬件-笔试面试题】硬件/电子工程师&#xff0c;笔试面试题汇总版&#xff0c;持…

Ethereum: 从 1e+21 到千枚以太币:解密 Geth 控制台的余额查询

大家好今天&#xff0c;我们来聊一个新手在接触以太坊节点时经常会遇到的场景。想象一下&#xff0c;我们成功运行了一个私有以太坊节点&#xff0c;并尝试查询一个账户的余额&#xff0c;然后我们看到了这样一个返回结果&#xff1a;1e21。 这是什么意思&#xff1f;是出错了&…

2025最新软件测试面试八股文(含答案+文档)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、什么是POM&#xff0c;为什么要使用它&#xff1f;POM是Page Object Model的简称&#xff0c;它是一种设计思想&#xff0c;而不是框架。大概的意思是&#xff…

表格数据处理-TabNet模型使用说明(模型构建+SHAP)

一、模型介绍 论文为《TabNet: Attentive Interpretable Tabular Learning》发表于2021年&#xff0c;属于Google Cloud AI。该研究针对表格数据提出了一种新的深度神经网络&#xff08;DNN&#xff09;架构TabNet&#xff0c;旨在解决传统深度学习在表格数据上表现不如决策树模…

数据集成难在哪?制造企业该怎么做?

目录 一、为什么你的数据集成总失败&#xff1f; 1.数据没有统一标准 2.数据 “断点多”&#xff0c;打通成本高 3.数据 “用不起来”&#xff0c;价值难落地 二、数据集成的正确做法是什么&#xff1f; 第一步&#xff1a;明确 “集成为了谁”— 用业务目标倒推数据需求…

Datawhale AI数据分析 作业2

学生考试表现影响因素数据集第一步&#xff1a;数据概览与清洗Prompt 1:加载StudentPerformanceFactors.csv文件&#xff0c;并显示前5行数据以及各列的数据类型和非空值数量&#xff0c;检查是否存在缺失值。处理缺失值是数据预处理的重要一步。对于您提到的缺失值&#xff1a…

Flowable 与 Spring Boot 深度集成:从环境搭建到平台构建

在前三篇文章中&#xff0c;我们依次认识了 Flowable 的基础概念、用 Modeler 设计流程&#xff0c;以及通过 API 控制流程运行。但在实际项目中&#xff0c;我们更需要将 Flowable 与 Spring Boot 深度融合&#xff0c;构建完整的工作流平台。本文将从环境配置、设计器集成、权…

Jenkins最新版本的安装以及集成Allure生成测试报告

目录 Jenkins的安装 将上面的目录添加到系统环境变量中 为Jenkins配置密码 创建一个用户&#xff0c;用于登录jenkins 为Jenkins安装Allure插件 几个大坑 使用jenkins集成python测试项目 Jenkins的安装 Jenkins官方网址 Jenkins 点击download 点击 past Release选择你想要下载…

Vue3 面试题及详细答案120道 (1-15 )

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…