JVM GC 算法原理概述

对于JVM的垃圾收集(GC),这是一个作为Java开发者必须了解的内容,那么,我们需要去了解哪些内容呢,其实,GC主要是解决下面的三个问题:

  • 哪些内存需要回收?

  • 什么时候回收?

  • 如何回收?

回答了这三个问题,也就对于GC算法的原理有了最基本的了解。

1 如何判定哪些内存需要回收


  在Java虚拟机的堆中会存放着很多的对象,那么,我们需要回收垃圾的时候,是通过什么算法来判断哪些垃圾的生命周期已到,需要回收呢?接下来的几种算法将帮助你解决这几个问题。

引用计数算法

先讲讲第一个算法:引用计数算法

  其实,这个算法的思想非常的简单,一句话就是:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器加1;当引用失效时,计数器减1;任何时刻计数器为0的对象就是不可能再被使用的。

  这些简单的算法现在是否还被大量的使用呢,其实,现在用的已经不多,没有被使用的最主要的原因是他有一个很大的缺点很难解决对象之间循环引用的问题

  循环引用:当A有B的引用,B又有A的引用的时候,这个时候,即使A和B对象都为null,这个时候,引用计数算法也不会将他们进行垃圾回收。

public class Test_02 {public static void main(String[] args) {Instance instanceA = new Instance();Instance instanceB = new Instance();instanceA.instance = instanceB;instanceB.instance = instanceA;instanceA = null;instanceB = null;System.gc();Scanner scanner = new Scanner(System.in);scanner.next();}
}class Instance{public Object instance = null;
}

如果使用的是引用计数算法,这是不能被回收的,当然,现在的JVM是可以被回收的。

可达性分析算法

  这个算法的思想也是很简单的,这里有一个概念叫做可达性分析,如果知道图的数据结构,这里可以把每一个对象当做图中的一个节点,我们把一个节点叫做GC Roots,如果一个节点到GC Roots没有任何的相连的路径,那么就说明这个节点不可达,也就是这个节点可以被回收。

上面图中,虽然obj7、8、9相互引用,但是到GC Roots不可达,所以,这种对象也是会被当做垃圾收集的。

在Java中,可以作为GC Roots的对象包括以下几种:

  • 虚拟机栈(栈帧中的局部变量表,Local Variable Table)中引用的对象。

  • 方法区中类静态属性引用的对象。

  • 方法区中常量引用的对象。

  • 本地方法栈中JNI(即一般说的Native方法)引用的对象。

2 什么时候回收


  在可达性分析算法中不可达的对象,也不是一定会死亡的,它们暂时都处于“缓刑”阶段,要真正宣告一个对象“死亡”,至少要经历两次标记过程。

step1:判断有没有必要执行finalize()方法
  • 如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行`finalize()`方法

另外,有两种情况都视为“没有必要执行”:

  • 对象没有覆盖finaliza()方法。

  • finalize()方法已经被虚拟机调用过。

step2:如何执行

  如果这个对象被判定为有必要执行finalize()方法,那么此对象将会放置在一个叫做 F-Queue 的队列中,并在稍后由一个虚拟机自动建立的、低优先级的Finalizer线程去执行它。

step3:执行死亡还是逃脱死亡

首先,我们需要知道,finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue 队列中的对象进行第二次小规模的标记。

  • 逃脱死亡:对象想在finalize()方法中成功拯救自己,只要重新与引用链上的任何一个对象建立关联即可,例如把自己(this关键字)赋值给某个类变量或者对象的成员变量,这样在第二次标记时它将被移出“即将回收”的集合。

  • 执行死亡:对象没有执行逃脱死亡,那就是死亡了。

3 如何回收


  如何回收其实就是利用哪些算法进行回收,垃圾收集算法这里讲几种大家平时也是看到的比较的算法,分别为:标记-清除算法复制算法标记-整理算法分代回收算法

  这部分的内容其实在网上的文章比较多了,而且,基本上的差别不大,所以,从网上的文章选取下来,当做一个小的总结,大家可以参考这篇文章算是一个比较全的总结:GC算法与内存分配策略。

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

  标记-清除(Mark-Sweep) 算法是最基础的垃圾收集算法,后续的收集算法都是基于它的思路并对其不足进行改进而得到的。顾名思义,算法分成“标记”、“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,标记过程在前一节讲述对象标记判定时已经讲过了。

标记-清除算法的不足主要有以下两点:

  • 空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不触发另一次垃圾收集动作。

  • 效率问题,因为内存碎片的存在,操作会变得更加费时,因为查找下一个可用空闲块已不再是一个简单操作。

标记-清除算法的执行过程如下图所示:

复制(Copying)算法

  为了解决标记-清除算法的效率问题,一种称为“复制”(Copying)的收集算法出现了,思想为:它将可用内存按容量分成大小相等的两块,每次只使用其中的一块。当这一块内存用完,就将还存活着的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。

  这样做使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。只是这种算法的代价是将内存缩小为原来的一半,代价可能过高了。复制算法的执行过程如下图所示:

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

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

  根据老年代的特点,标记-整理(Mark-Compact)算法被提出来,主要思想为:此算法的标记过程与标记-清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。 具体示意图如下所示:

分代收集(Generational Collection)算法

  当前商业虚拟机的垃圾收集都采用分代收集(Generational Collection)算法,此算法相较于前几种没有什么新的特征,主要思想为:根据对象存活周期的不同将内存划分为几块,一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适合的收集算法:

  • 新生代 在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

  • 老年代 在老年代中,因为对象存活率高、没有额外空间对它进行分配担保,就必须使用标记-清除标记-整理算法来进行回收。

4 总结

这里用思维导图做一个小的总结。

参考

  堆外内存的回收机制分析 https://www.jianshu.com/p/35cf0f348275 

  java调用本地方法--jni简介 https://blog.csdn.net/w1992wishes/article/details/80283403 

  咱们从头到尾说一次 Java 垃圾回收 https://mp.weixin.qq.com/s/pR7U1OTwsNSg5fRyWafucA 

  深入理解 Java 虚拟机 

  Java Hotspot G1 GC的一些关键技术 Java Hotspot G1 GC的一些关键技术 - 美团技术团队

附:关于GC Roots的理解


所谓“GC roots”,或者说tracing GC的“根集合”,就是一组必须活跃的引用
例如说,这些引用可能包括:

  • 所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用;换句话说,当前所有正在被调用的方法的引用类型的参数/局部变量/临时值。
  • VM的一些静态数据结构里指向GC堆里的对象的引用,例如说HotSpot VM里的Universe里有很多这样的引用。
  • JNI handles,包括global handles和local handles
  • (看情况)所有当前被加载的Java类
  • (看情况)Java类的引用类型静态变量
  • (看情况)Java类的运行时常量池里的引用类型常量(String或Class类型)
  • (看情况)String常量池(StringTable)里的引用

注意,是一组必须活跃的引用,不是对象。

  Tracing GC的根本思路就是:给定一个集合的引用作为根出发,通过引用关系遍历对象图,能被遍历到的(可到达的)对象就被判定为存活,其余对象(也就是没有被遍历到的)就自然被判定为死亡。注意再注意:tracing GC的本质是通过找出所有活对象来把其余空间认定为“无用”,而不是找出所有死掉的对象并回收它们占用的空间。
GC roots这组引用是tracing GC的起点。要实现语义正确的tracing GC,就必须要能完整枚举出所有的GC roots,否则就可能会漏扫描应该存活的对象,导致GC错误回收了这些被漏扫的活对象。

  这就像任何递归定义的关系一样,如果只定义了递推项而不定义初始项的话,关系就无法成立——无从开始;而如果初始项定义漏了内容的话,递推出去也会漏内容。

那么分代有什么好处?

  对传统的、基本的GC实现来说,由于它们在GC的整个工作过程中都要“stop-the-world”,如果能想办法缩短GC一次工作的时间长度就是件重要的事情。如果说收集整个GC堆耗时太长,那不如只收集其中的一部分?
  于是就有好几种不同的划分(partition)GC堆的方式来实现部分收集,而分代式GC就是这其中的一个思路。

  这个思路所基于的基本假设大家都很熟悉了:weak generational hypothesis——大部分对象的生命期很短(die young),而没有die young的对象则很可能会存活很长时间(live long)。

  这是对过往的很多应用行为分析之后得出的一个假设。基于这个假设,如果让新创建的对象都在young gen里创建,然后频繁收集young gen,则大部分垃圾都能在young GC中被收集掉。由于young gen的大小配置通常只占整个GC堆的较小部分,而且较高的对象死亡率(或者说较低的对象存活率)让它非常适合使用copying算法来收集,这样就不但能降低单次GC的时间长度,还可以提高GC的工作效率。

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

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

相关文章

【1】Docker详解与部署微服务实战

Docker 详解 Docker 简介 Docker 是一个开源的容器化平台,可以帮助开发者将应用程序和其依赖的环境打包成一个可移植、可部署的容器。Docker 的主要目标是通过容器化技术实现应用程序的快速部署、可移植性和可扩展性,从而简化应用程序的开发、测试和部…

ElementUI的Table组件行合并上手指南

ElementUI的Table组件行合并 &#xff0c;示例用官网vue3版的文档 <el-table :data"tableData" :span-method"objectSpanMethod" border style"width: 100%; margin-top: 20px"><el-table-column prop"id" label"ID&qu…

VS配置PCO相机SDK环境

VS配置PCO相机SDK环境 概述:最近要用到一款PCO相机,需要协调其他部件实现一些独特的功能。因此需要用到PCO相机的SDK,并正确配置环境。良好的环境是成功的一半。其SDK可以在官网下载,选择对应版本的安装即可。这里用的是pco.cpp.1.2.0 Windows,VS 2022 专业版。 链接: P…

【TensorFlow 精简版】TensorFlow Lite

目录 一 TensorFlow Lite简介 二 开发 三 开始使用 一 TensorFlow Lite简介 TensorFlow Lite 是一组工具&#xff0c;可帮助开发者在移动设备、嵌入式设备和 loT 设备上运行模型&#xff0c;以便实现设备端机器学习。 针对设备端的机器学习进行的优化&#xff1a; ① 延时&…

oracle下载

前言&#xff1a; 官网上提供都是最新的什么19c 21c这些版本&#xff0c;我要的是 11g 12c 或者更老的 8i 9i 这些版本。 准备下载一个oracle12c 版本&#xff0c;但是找了很久&#xff0c;最终…详情请看下面 oracle 数据库版本介绍 Oracle数据库有多个长期支持版本&#x…

格密码基础:子格,q-ary垂直格与线性代数

目录 一.写在前面 二.子空间垂直 2.1 理论解释 2.2 举例分析 三. 零空间 3.1 零空间与q-ary垂直格 3.2 零空间与行/列空间 四. 格密码相关 一.写在前面 格密码中的很多基础原语都来自于线性代数的基本概念&#xff0c;比如举几个例子&#xff1a; 格密码中的非满秩格…

2022年全球软件质量效能大会(QECon上海站)-核心PPT资料下载

一、峰会简介 近年来&#xff0c;以云计算、移动互联网、物联网、工业互联网、人工智能、大数据及区块链等新一代信息技术构建的智能化应用和产品出现爆发式增长&#xff0c;突破了对于软件形态的传统认知&#xff0c;正以各种展现方式诠释着对新型智能软件的定义。这也使得对…

❀My小学习之排序算法❀

目录 排序算法&#xff08;Sorting algorithm&#xff09;:) 一、定义 二、分类 三、评价标准 排序算法&#xff08;Sorting algorithm&#xff09;:) 一、定义 所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的…

docker学习(十九、network使用示例bridge)

文章目录 一、容器网络分配情况1.启动容器2.查看容器的network3.容器网络分配 二、bridge1.bridge详细介绍2.实践bridge两两匹配3.创建network&#xff0c;默认bridge network相关内容&#xff1a; docker学习&#xff08;十八、network介绍&#xff09; docker学习&#xff08…

一.windows2012搭建fpt服务器和常见端口介绍

一.windows2012搭建fpt服务器和常见端口介绍 1.打开防火墙2.创建组2.1打开计算机管理2.2创建组并且设置名称和描述 3.创建用户3.1设置用户密码和名称3.2把用户归属于组3.3把user删除掉3.4点击添加然后点高级3.5点击立即查找选择之前设定的组 4.安装ftp服务器4.1点击添加角色和功…

仓储革新:AR技术引领物流进入智慧时代

根据《2022年中国物流行业研究&#xff1a;深度探析行业现状&#xff08;智能设备及智能软件&#xff09;》&#xff0c;报告中提及&#xff1a;“中国社会物流总额依然保持着较为良好的增长态势&#xff0c;年增速已恢复至常年平均水平。2021年社会物流总额细分中工业物流总额…

千巡翼X4轻型无人机 赋能智慧矿山

千巡翼X4轻型无人机 赋能智慧矿山 传统的矿山测绘需要大量测绘员通过采用手持RTK、全站仪对被测区域进行外业工作&#xff0c;再通过方格网法、三角网法、断面法等进行计算&#xff0c;需要耗费大量人力和时间。随着无人机航测技术的不断发展&#xff0c;利用无人机作业可以大…

javaEE -18(11000字 JavaScript入门 - 3)

一&#xff1a;事件 &#xff08;高级&#xff09; 1.1 注册事件&#xff08;绑定事件&#xff09; 给元素添加事件&#xff0c;称为注册事件或者绑定事件&#xff0c;注册事件有两种方式&#xff1a;传统方式和方法监听注册方式 传统注册方式 &#xff1a; 利用 on 开头的…

20231227在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单后摄像头ov13850

20231227在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单后摄像头ov13850 2023/12/27 18:40 1、简略步骤&#xff1a; rootrootrootroot-X99-Turbo:~/3TB$ cat Android11.0.tar.bz2.a* > Android11.0.tar.bz2 rootrootrootroot-X99-Turbo:~/3TB$ tar jxvf Androi…

Find My化妆包|苹果Find My技术与化妆包结合,智能防丢,全球定位

化妆包顾名思义&#xff0c;那就是装载、收纳化妆品的包包&#xff0c;从而方便妹子可以随时随地取用。化妆包可以说是内有乾坤&#xff0c;比如睫毛膏、唇彩、粉饼、眉笔、防晒霜、吸油纸等等。按功能分为多功能型专业化妆包&#xff0c;旅游用简约型化妆包和家用小化妆包。按…

组织框架概念澄清及表设计

组织 企业组织 企业组织就是企业正式编制&#xff0c;以单独的编制&#xff0c;是个人在企业所在的长久的家&#xff0c;类似于所说的考编&#xff0c;在企业体制内的位置&#xff0c;可能一个人在组织有不同的岗位&#xff0c;也可能有不同的项目组&#xff0c;但是&#xf…

21.仿简道云公式函数实战-数学函数-COS

1. COS函数 COS 函数可用于计算角度的余弦值&#xff0c;返回 -1 到 1 之间的数值。 2. 函数用法 COS(弧度) 3. 函数示例 如计算 COS(60) 的值&#xff0c;可设置公式为COS(RADIANS(60))&#xff0c;返回 0.5。 4. 代码实战 首先我们在function包下创建math包&#xff0…

被他人错误解析域名到雷池 WAF网关的处理办法

作者&#xff1a;田逸 最近一些项目的站点经常发告警短信&#xff0c;提示网站无法访问。通过排查&#xff0c;发现后端数据库资源都被耗尽&#xff08;连接数上千&#xff0c;正常情况是小于100&#xff09;&#xff0c;负载也高得吓人&#xff0c;如下图所示。 “load averag…

照着这几步做,轻松搭建企业知识库

在当今信息爆炸的时代&#xff0c;企业面临着海量的知识和信息。如何高效地管理和利用这些知识成为了企业发展的关键。而搭建一个适合企业的知识库&#xff0c;可以帮助企业更好地组织和共享知识&#xff0c;提高工作效率和竞争力。下面将为大家介绍一些简单的步骤&#xff0c;…

Xshell 从github克隆项目:使用ssh方式。

接上文&#xff1a; https://blog.csdn.net/liu834189447/article/details/135247868 是能克隆项目了&#xff0c;但是速度太磕碜了&#xff0c;磕碜到难以直视。 找到另外一种办法&#xff0c;使用SSH克隆项目 速度嘎嘎猛。 首先得能进得去github网站&#xff0c;不能点上边…