JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法

垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域? 垃圾回收如何去回收? 垃圾回收策略 引用计数算法及循环引用问题 可达性分析算法

  • 垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?
    • 垃圾回收如何去回收?
      • 垃圾回收策略
    • 引用计数算法及循环引用问题
    • 可达性分析算法
  • 思考
  • 汇总

垃圾回收如何去回收?
垃圾回收策略
引用计数算法及循环引用问题
可达性分析算法)

垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?

请添加图片描述
JVM内存模型认识的差不多了,就应该思考,什么样的内存模型适合什么样的GC策略,包括垃圾回收为什么会出现。实际上,很多东西都是相对应版本的JVM强加上去的。那么垃圾回收是什么?到底回收哪块区域?如何去回收?

这个时候观察运行时数据区来进行分析。
线程私有的区域是完全没有必要回收的,因为方法消亡就消亡了,它的生命周期很短,会伴随着你的方法的退出而消亡,因此不必关心它的回收,而且类文件结构确定之后,就知道整个方法当中字节码指令流转的一个情况了,所以不需要对这块区域进行关心。

线程共享的区域是方法区和堆这两块区域,而方法区MetaSpace中,实际上它的回收有没有呢?有的,但是很少,或者说回收的效率并不高,因为方法区当中的数据是静态变量,常量,字符串常量池,类信息,即时编译后的代码,它的生命周期一般都很长,随着程序运行一段时间之后,它占用方法区的那一块内存会趋于稳定,因为这些东西不回收,所以回收重点关注的地方还是这个区域。因为Java是一门面向对象的一门高级语言,所以对象的创建以及回收才是最重要的。而我们的GC,或者说所谓的垃圾回收,更多的是对于堆内存这块区域的回收,来进行讨论。

那么堆要进行回收的话,到底要怎么去进行回收呢?

垃圾回收如何去回收?

首先需要考虑的第一个问题:什么样的场景下适合使用什么样的垃圾回收策略。
这里注意策略和算法是不一样的,算法是真正落地的实现,而策略不一定要落地。

回收策略按照我们的思想去设计优化的话,首先肯定要关注内存的使用情况,因为垃圾回收本身就是一种穷人策略,因为没有那么多内存共我们去挥霍,所以才会想尽办法提高我们垃圾回收的效率。

垃圾回收策略

  • 收的多: 收的多,意味着收的久。尽可能每次多回收一些对象,尽可能多腾出一些内存,而收的多意味着收的久。
  • 收的快: 收的快,意味着每次收的少需要多次回收。最好可以将时间缩短到一次网络延迟,哪怕回收次数很多都可以容忍,这样收再多次都是无所谓的。

因此会在垃圾回收的时间上和CPU的效率上有个抉择,假设CPU使用率过高,那么可以尽可能的去调低垃圾回收的一个频率,使得CPU的使用率能够在我们接受的范围内,也就是可控性回收

比如我们平时收拾屋子,那么首先就是确定屋子多大,然后哪些东西是垃圾。程序亦是如此,hotsport的开发者也会有这样的想法,它需要有一套判断当前对象是垃圾的依据(或者叫算法)。那么在程序当中,所有的执行逻辑、判断逻辑都可以称之为算法,因为程序就是逻辑+数据组成的。

为什么回收选取操作性较高的数据?
举个例子,你在家里扫垃圾,肯定也是选择比较容易清理的哪些东西叫做垃圾,不好拿的和好拿的肯定先选好拿的。那么在当前的场景中,我们操作性较高的数据是对象,因此是根据对象去进行一个讨论。

而在Java中,引用和对象显然是有关联的,如果要操作对象,必然是会引用来去执行,那么这个时候,最显然的一个办法就是通过引用计数来判断对象是否可以回收,简单的来说,如果一个对象没有任何与之相关联的引用,即它们的引用计数都为0的情况下,也就是说,这个对象没有任何场景下可能会使用到它了,那这个对象就是可回收对象,这就是引用计数法。但是现在Java主流算法并不是这个,因为它难以解决循环引用的问题。

引用计数算法及循环引用问题

/*** 引用计数法难以解决循环引用问题*/
public class CircularReferenceDemo {public static void main(String[] args) {CircularReferenceObject obj1 = new CircularReferenceObject();CircularReferenceObject obj2 = new CircularReferenceObject();/*** 这两句代码表示:* 第一步:虚拟机栈有两个东西obj1、obj2,它是虚拟机栈中的局部变量表中的元素* 第二步:new两个CircularReferenceObject对象,这两个对象是不同的CircularReferenceObject实例,在堆当中共开辟两个内存地址* 第三步:obj1指向堆中的实例1,obj2指向堆中的实例2** 此时此刻,堆中的这两个实例的引用计数应该各自+1=1*/obj1.instance = obj2;obj2.instance = obj1;/*** 让堆中的两个实例互相引用,obj1指向obj2,obj2指向obj1** 此时此刻,堆中的这两个实例的引用计数应该各自再+1=2*/obj1 = null;obj2 = null;/*** 赋值为null,表示不再指向任何数据,即栈中元素不再指向堆中实例** 此时此刻,堆中的这两个实例的引用计数应该各自-1=1** 这个时候,循环引用问腿就来了:按照引用计数法,堆中这两个实例各自的引用计数都不为0,也就是说这两个实例所占用的堆内存空间无法释放** 系统给到实例内存空间但是无法释放的这种情况称之为内存泄露,如果这种情况一直发生,最终会导致内存溢出,因此主流的JVM已经摒弃了这种算法*/}static class CircularReferenceObject {public Object instance = null;}
}

请添加图片描述
对于对象之间的循环引用问题,其实引用计数法它会有策略进行解决,但是这个不是Java应该关心的事情。Java中已经摒弃了引用计数法这种算法,python还在用,引用计数法这种算法的效率会比另一种算法快的多,既然主流的JVM已经摒弃了这种算法,那么必然会出现一种新的算法对它进行替代,来解决循环引用的问题,最少也是让所谓循环引用的问题带来的影响没那么大,那么另一种算法横空出世,就是可达性分析算法。

可达性分析算法

可达性分析算法,也被称为根搜索算法,目前主流的JVM都是采用的这种算法,比如Sun公司的hotsport。
这个算法的核心是从所谓的GC root进行出发,也就是从一个所谓的根进行出发,利用数学中的图论(Graph Theory)知识,从根触发,单条引用链能够到达的对象,便是存活对象,反之即为不可达对象,不可达对象就是需要回收的垃圾。

这里面涉及到两个概念根(所谓的GC root)和可达性。所谓的根、GC root只是一种引用,它并不是对象,它只是告诉你地址,让你知道如何找对象。

哪些可以作为GC root的对象?

  • 虚拟机栈中的局部变量表中的元素Object obj = new Object();,这种new出来的对象,必然是我们需要的对象,所以obj这种位于虚拟机栈中的局部变量表中的元素必然可以作为GC root
  • 方法区的静态变量以及常量
  • 本地方法栈JNI中的元素

思考

引用到底是什么?不同引用会有什么作用?不同引用会不会有不同的监控策略?如果可达性分析算法标记为不可达会立即进行垃圾回收吗?常说的标记整理又是做什么的?

汇总

JVM1:官网了解JVM;Java源文件运行过程、javac编译Java源文件、如何阅读.class文件、class文件结构格式说明、 javap反编译字节码文件;类加载机制、class文件加载方式

JVM2:类加载机制、class文件加载方式;类加载的过程:装载、链接、初始化、使用、卸载;类加载器、为什么类加载器要分层?JVM类加载机制的三种方式:全盘负责、父类委托、缓存机制;自定义类加载器

JVM3:图解类装载与运行时数据区,方法区,堆,运行时常量池,常量池分哪些?String s1 = new String创建了几个对象?初识栈帧,栈的特点,Java虚拟机栈,本地方法发栈,对象指向问题

JVM4:Java对象内存布局:对象头、实例数据、对齐填充;JOL查看Java对象信息;小端存储和大端存储,hashcode为什么用大端存储;句柄池访问对象、直接指针访问对象、指针压缩、对齐填充及排序

JVM5:JVM内存模型与运行时数据区的关系,堆为什么分区,分代年龄,Young区划分,Survivor区为什么分为S0和S1,如何理解各种GC:Partial GC、Full GC、Young GC

JVM6:JVM内存模型验证;使用visualvm查看JVM视图;Visual GC插件下载链接;模拟JVM常见错误,模拟堆内存溢出,模拟栈溢出,模拟方法区溢出

JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法

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

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

相关文章

ctfshow web入门 web103-web107

1.web103 和102一样 payload: v2115044383959474e6864434171594473&v3php://filter/writeconvert.base64-decode/resource1.php post v1hex2bin2.web104 值只要一样就可以了 payload: v21 post v113.web105 考查的是$$变量覆盖,die可以带出数据,输出一条消息&#xf…

C# winform加载yolov8模型测试(附例程)

第一步:在NuGet中下载Yolov8.Net 第二步:引用 using Yolov8Net; 第三步:加载模型 private IPredictor yolov8 YoloV8Predictor.Create("D:\\0MyWork\\Learn\\vs2022\\yolov_onnx\\best.onnx", mylabel); 第四步:图…

c++存取dat数据

众所周知,dat是一个类似加密的二进制格式文件,很多人喜欢将游戏数据保存在dat文件中,只有知道你的存放格式,才能够将数据破解出来,因而研究了dat文件的存取方式。其实就是c文件的操作,只不过是在取的时候需…

0基础入门C++之类和对象下篇

目录 1.再谈构造函数1.1构造函数赋值1.2初始化列表1.3explicit关键字 2.static成员2.1概念2.1静态成员变量2.2静态成员函数2.3特性 3.匿名对象4.友元函数4.1友元函数4.2友元类 5.内部类6.再次理解类和对象 1.再谈构造函数 首先我们先来回忆一下构造函数: 构造函数是…

华为OD-整数对最小和

题目描述 给定两个整数数组array1、array2,数组元素按升序排列。假设从array1、array2中分别取出一个元素可构成一对元素,现在需要取出k对元素,并对取出的所有元素求和,计算和的最小值 代码实现 # coding:utf-8 class Solution:…

【工具使用】Git的使用

dev代表开发版 1. git clone 命令 通过 git add <name> 对文件进行跟踪&#xff0c;把<name>加入到暂存区 git commit -m XXXXXXX 提交修改并补充XXXXX作为注释 “暂存”状态&#xff1a;出现了一些修改&#xff0c;但是还没有提交 对于Java来说&#xff0c;.cl…

goland 中的调试器 -- Evaluate

今天一个好朋友 找到我&#xff0c;问我关于goland中Evaluate 小计算器的使用方式&#xff0c;说实话&#xff0c;我在此之前也没用过这个东西&#xff0c;然后我就找一些相关文档&#xff0c;但是这类文档少的可怜&#xff0c;所以我就稍微研究一下&#xff0c;找找材料&#…

数组名和函数名是指针?指针和引用底层一样?

在2023/8/26日晚上&#xff0c;我看到一个所谓“典”的视频&#xff0c;一开始还没太在意&#xff0c;后面想了想发现我貌似也一直犯了以下的错误&#xff0c;而错误的原因在于我在新手阶段学习C/C并不是查阅文档扎好脚步学习的&#xff0c;而是被铺天盖地的新手学习基础教程里…

Java“牵手”天猫商品列表数据,关键词搜索天猫商品数据接口,天猫API申请指南

天猫商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取天猫商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问天猫商城的网页来获取商品详情信息。以下是两种常用方法的介绍&…

Vue2向Vue3过度Vuex核心概念actions

目录 1 核心概念 - actions1.定义actions2.组件中通过dispatch调用 2 辅助函数 -mapActions 1 核心概念 - actions state是存放数据的&#xff0c;mutations是同步更新数据 (便于监测数据的变化, 更新视图等, 方便于调试工具查看变化)&#xff0c; actions则负责进行异步操作 说…

云南森林火灾vr消防模拟安全演练系统训练消防员火灾和事故的适应和应对能力

据统计,每一场破坏性地震发生后,会引发次生的灾害,而火灾是其中之一。导致火灾的原因,推测是地震时使供电线路短路,引燃易燃物,火灾就随即发生。所以,在日常生活中,定期的消防演练还是非常必要的, VR消防&#xff0c;是VR公司深圳华锐视点利用VR虚拟现实技术&#xff0c;将VR和…

Unity项目如何上传Gitee仓库

前言 最近Unity项目比较多&#xff0c;我都是把Unity项目上传到Gitee中去&#xff0c;GitHub的话我用的少&#xff0c;可能我还是更喜欢Gitee吧&#xff0c;毕竟Gitee仓库用起来更加方便&#xff0c;注意Unity项目上传时最佳的方式是把 Asste ProjectSetting 两个文件夹上传上…

CFC编程入门_【10分钟学会】

什么是CFC&#xff1a; 【差不多10分钟全学会】 CFC是图形化编程&#xff0c; 跟单片机的连线一样&#xff0c; 唯一的区别&#xff1a;功能块右侧是【只能输出】引脚。 只有左侧引脚可以输入输出。 有哪些控件&#xff1a; 指针&#xff1a;用于拖动功能块。 控制点&#xf…

<七> objectARX开发:创建自定义实体

1、介绍 在某些情况下,CAD中的实体对象无法满足需求,我们需要针对实际情况来设计并绘制自定义的实体,下面就用一个简单的例子来介绍一下自定义实体绘制。 实体形状:包括实体夹点和文字夹点拖动实现。 2、效果 3、创建自定义实体的步骤 新建一个从AcDbEntity继承的类,如C…

谷歌面试-扔鸡蛋

今天想跟大家分享一个有意思的面试题&#xff0c;这让我再一次感叹思维的奇妙&#xff0c;接下来我们一起看看吧~ 首先来看看题目&#xff1a; 你有2颗鸡蛋&#xff0c;需要以最少的尝试次数来判断在100层的高楼上&#xff0c;哪一层楼是鸡蛋的安全层。 换句话说&#xff0c…

(java) 进程调度

目录 进程 首先我们要了解一下什么是进程&#xff1f; 那如何管理进程&#xff1f; PCB中比较重要的属性 进程调度 为什么要进行进程调度&#xff1f; 状态 优先级 上下文 拓展介绍一下寄存器 记账信息 进程 首先我们要了解一下什么是进程&#xff1f; 简单来说…

mongodb聚合排序的一个巨坑

现象&#xff1a; mongodb cpu动不动要100%&#xff0c;如下图 分析原因&#xff1a; 查看慢日志发现&#xff0c;很多条这样的查询&#xff0c;一直未执行行完成&#xff0c;占用大量的CPU [{$match: {"tags.taskId": "64dae0a9deb52d2f9a1bd71e",grnty: …

全流程R语言Meta分析核心技术应用

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;最早出现于“循证医学”&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面。…

【Qt学习】05:自定义封装界面类

OVERVIEW 自定义封装界面类1.QListWidget2.QTreeWidget3.QTableWidget4.StackedWidget5.Others6.自定义封装界面类-显示效果&#xff08;1&#xff09;添加设计师界面类&#xff08;2&#xff09;在ui中设计自定义界面&#xff08;3&#xff09;在需要使用的界面中添加&#xf…