JVM垃圾回收机制(GC)

目录

1.什么是垃圾回收

2.GC对于虚拟机各块的影响

3.垃圾回收具体是怎么展开的

3.1引入计数

3.2可达性分析(JVM使用的就是这种方法)

3.2.1.标记清除

3.2.2.复制算法

3.3.3标记整理

3.3分代回收


1.什么是垃圾回收

       在C语言等编程语言中,采用的是动态内存管理,我们使用malloc申请内存,free释放内存,在malloc这种方式申请到的内存是伴随整个进程的生命周期的,这一点对于服务器非常不友好,因为服务器每个请求都去malloc一块内存,如果不去free释放,在内存越来越多的时候,后续内存可能就申请不到了,因为被申请完了. 这就是著名的内存泄漏问题,实际开发中,经常在使用maclloc申请内存后,忘记使用free释放内存了,或者因为某些情况没有执行到free函数.这其实对于开发工作来说很不友好,Java 为了解决这种问题,引入了垃圾回收机制,引入这种机制以后,就不需要手动去释放内存了,程序会自动判定,某个内存是否会继续使用,如果后续不用了,就会被自动释放掉,在Java中释放的就是对象.

2.GC对于虚拟机各块的影响

  JVM中有好几块内存,那么GC这种机制对于各个部分有什么影响呢?

1.程序计数器(不需要GC)

2.栈(也不需要GC) 局部变量在代码块执行结束以后自动销毁了 栈自己的特点就是这样,所以不需要GC

3.元数据区(方法区)一般都是涉及到类加载,很少涉及到类卸载

4.堆是GC的主要战场(对象的释放)

3.垃圾回收具体是怎么展开的

1.识别出垃圾,判断这个对象后续是否还要继续使用,在Java中使用对象,一定需要通过引用的方式来使用(除了匿名对象)

如果一个对象没有任何引用指向它,就视为是无法被代码使用,就可以视为垃圾了

如: 

void func(){Test() = new Test();t.start();
}

此时通过new Test就是是堆上创建了对象,当代码执行到 } 的时候,此后的局部变量就直接被释放掉了,此时如果更进一步的去想,上述 new Test()对象,也就是没有引用指向它了,  此时这个对象没有被这些代码访问到,这个对象就是垃圾了. 如果代码更加复杂一些,这个判断就会更复杂了.

3.1引入计数

这种思想方法,并没有在JVM中使用,但是广泛应用在其它主流语言的垃圾回收机制中,如python php等,即给每个对象分配一个额外的空间,这个空间保存这个对象的引用个数有多少个.

 此时的垃圾回收机制,会有专门的扫描线程,去获取到当前每个对象的引用计数情况,发现对象的引用计数为0,说明这个对象就可以释放了(就是垃圾了)

引用计数是一个简单有效的机制,但是有两个关键的问题.

问题1:消耗额外的内存空间,要给每个对象安排一个计数器,即使一个计数器只有两个字节来算,如歌整个程序中的对象数目很多,消耗的额外空间也会非常多,尤其是当这个对象的体积比较小的时候,计数器消耗的空间占比就更大了.

问题2 引用计数可能会产生循环引用的问题,此时 引用计数就可能无法正确工作了.

class Test(){Test t;
}
Test a = new Test();
Test b = new Test();a.t = b;b.t = a;a = null;b = null;
//上述的代码出现了问题就是,上述的两个对象 引用计数都不是0.不能被GC挥手,但是这两个对象又无法使用/

3.2可达性分析(JVM使用的就是这种方法)

本质上是以时间换取空间,相比于计数,需要消耗额外的时间去扫描,但是总体来说是可控的.不会产生"循环引用''这种问题,

在写代码的时候,会定义很多的变量.比如,栈上的局部变量.方法区的静态类型的变量/常量池中引用的对象

就可以以这些变量为起点,出发去尝试遍历,所谓的便利就是,会沿着这些变量中持有的引用类型的成员,再进一步的往下进行访问

所有能被访问到的对象自然就不是垃圾了,剩下的遍历一圈也访问不到的对象,自然就是垃圾.

比如有以下代码,我们手动定义一颗二叉树:

class Node{char var ;Node left;Node right;
}
Node bulidTree{
Node a = new Node();
Node b = new Node();
Node c = new Node();
Node d = new Node();
Node e = new Node();
Node f = new Node();
Node g = new Node();
a.left = b;
a.right = c;
b.left = d;
b.right = e;
e.left = g;
c.right = f;
return a;
}

虽然这个代码,只有一个root这样的引用,但是实际上,上述七个节点都是可达的.

如果代码中出现 root.right = null 的时候,此时c就不可达了,此时c和f都会被释放掉.被视为垃圾

(2)把标记为垃圾的对象的内存空间进行释放.

具体怎么释放 还有说法,一般有三种方法 我们先简单的说一下前两种方法

3.2.1.标记清除

把标记为垃圾的对象直接释放掉, 这种方法过于简单粗暴,比如把下图黑色的视作垃圾对象,全部释放掉

会引起内存碎片问题,上述释放方式,会产生很多小的 但是离散的空间内存空间 

3.2.2.复制算法

 不直接释放内存,而是把不是垃圾的对象放到内存的另一半,接下来把左侧的全部释放掉.

虽然可以规避内存碎片问题 但是也会产生新的问题

(1) 总的可用空间变少

(2) 如果每次需要赋值的对象很多,这时候赋值所需要的开销也很大了,需要的是这一轮GC过程中,大部分对象都释放,少部分存活,这个时候适合复制.

3.3.3标记整理

类似于顺序表删除元素的操作,每次把存活的对象搬到前面的剩余空间去,但是这样也会有很大的开销

JVM使用的方法 取长补短, 称为分代回收

3.3分代回收

引入一个概念,对象的年龄

JVM中有专门的线程负责周期性的扫描(释放) 一个对象如果被线程扫描了一次,可达了(不是垃圾)就把它的年龄+1

JVM就会根据年龄的差异,把整个堆内存分为两大部分  新生代(年龄小的对象),老年代(年龄大的对象),在这中间还有一个生存区/幸存区

我们来详细的介绍一下这个过程

1.当代码new出来一个新的对象的时,就创建在伊甸区, (一个经验规律,大部分对象都活不过第一轮GC)

2.第一轮扫描以后,少数存活的对象,会通过复制算法,到生存区,后续的GC还会进行扫描,不仅要扫描伊甸区也要扫描生存区.只要这个对象继续在生存区存活,就会被复制算法拷贝到另一半的生存区,每一次扫描,对象的年龄都+1

3.如果这个对象在生存区经历了若干轮GC还在,那么就会被任务这个对象的生命周期大概率很长,就把这个对象从生存区,拷贝到老年代.

4.老年代的对象,也会被GC扫描,但是被扫描的频率会大大降低

5.对象在老年代寿终正寝,此时JVM就会按照标记整理的方式,释放内存

                                 

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

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

相关文章

SQL无列名注入

SQL无列名注入 ​ 前段时间,队里某位大佬发了一个关于sql注入无列名的文章,感觉好像很有用,特地研究下。 关于 information_schema 数据库: ​ 对于这一个库,我所知晓的内容并不多,并且之前总结SQL注入的…

【Java JVM】Class 文件的加载

Java 虚拟机把描述类的数据从 Class 文件加载到内存, 并对数据进行校验, 转换解析和初始化, 最终形成可以被虚拟机直接使用的 Java 类型, 这个过程被称作虚拟机的类加载机制。 与那些在编译时需要进行连接的语言不同, 在 Java 语言里面, 类的加载, 连接和初始化过程都是在程序…

如何打造企业工厂的多元化展示?VR数字工厂告诉你

随着数字化进程推进以及互联网大数据等技术的发展,很多行业逐渐开始了数字化转型,而企业工厂也需要与时俱进。VR数字工厂需要多元化展现自身实力,并打造专属于自己的AI数字人名片,力求在市场中凸显自己,那么如何利用VR…

短剧系统开发:一种新型的娱乐方式

一、引言 随着科技的快速发展,人们的生活方式也在逐渐改变。在娱乐领域,短剧作为一种新型的娱乐方式,正在受到越来越多人的喜爱。短剧以其短小精悍、情节紧凑、易于观看等特点,迅速占领了市场。因此,开发一款短剧系统…

计算机的基础知识

计算机的特点及应用: 图灵说–计算就是基于规则的符号串变换从20世纪80年代开始,发达国家开始研制第五代计算机,研究的目标是能够打破以往计算机固有的体系结构,使计算机能够具有像人一样的思维、推理和判断能力,向智…

AI最新!雷军、许礼进、曹文泽、屠红燕发声

源自:上海证券报 “人工智能技术与咨询” 发布 尽快出台专项,以智能制造系统软件、AI大模型和通用仿生机器人的部署应用为重点产业突破方向,支持打造以大模型为代表的人工智能与制造业深度融合的应用场景; 加快整合人形机器人产…

未来娱乐新境界:探秘充气式球幕影院的奇妙世界

充气式球幕影院,这一融合科技与创意的娱乐新宠,正在引领我们踏上一场前所未有的奇妙旅程。它不仅仅是对视觉和感官体验的极致追求,更以其独特的魅力,让我们在观影中沉浸于前所未有的震撼与享受。 半球形梦幻观影空间: …

基础50刷题之一(交替合并字符串)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、题目二、力扣官方题解(双指针)三、文心一言解释总结 前言 刚上研一,有人劝我好好学C,当时用的不多就没学&a…

SQL Server基础指令(创建与检索)

数据库demo 数据库RUNOOB 表Websites 元素: 创建 创建数据库 create database xxx Create database school 创建数据表 create table xxx create table student 数据表插入记录 insert into 第一种形式无需指定要插入数据的列名,只需提供被插入的…

【应用多元统计分析】--多元数据的直观表示(R语言作图)

例1.2 为了研究全国31个省、市、自治区2018年城镇居民生活消费的分布规律,根据调查资料做区域消费类型划分。 指标: 食品x1:人均食品支出(元/人) 衣着x2:人均衣着商品支出(元/人) 居住x3:人均居住支出(元/人) 生活x4…

C#,回文分割问题(Palindrome Partitioning Problem)算法与源代码

1 回文串 “回文串”是一个正读和反读都一样的字符串,初始化标志flagtrue,比如“level”或者“noon”等等就是回文串。 2 回文分割问题 给定一个字符串,如果该字符串的每个子字符串都是回文的,那么该字符串的分区就是回文分区。…

【Java】关于ZooKeeper的原理以及一致性问题,协议和算法和ZooKeeper的理论知识和应用 场景

1. 目录 目录 1. 目录 2. 什么是ZooKeeper 3. 一致性问题 4. 一致性协议和算法 4.1. 2PC(两阶段提交) 4.2. 3PC(三阶段提交) 4.3. Paxos 算法 4.3.1. prepare 阶段 4.3.2. accept 阶段 4.3.3. paxos 算法的死循环…