JVM的垃圾回收机制--GC

  垃圾回收机制,是java提供的对于内存自动回收的机制。java不需要像C/C++那样手动free()释放内存空间,而是在JVM中封装好了。垃圾回收机制,不是java独创的,现在应该是主流编程语言的标配。GC需要消耗额外的系统资源,而且存在非常影响执行效率的“STW”问题(触发GC的时候,可能一瞬间把系统负载拉满,导致服务器无法响应其他的请求)。

GC回收的“内存”,更准确说,是“对象”,回收的是“堆上的内存”。

内存区域有四块:

1)程序计数器(不需要额外回收,线程销毁,自然回收了)

2)栈(不需要额外回收,线程销毁,自然回收了)

3)元数据区(一般也不需要,都是加载类,很少“卸载类”)

4)堆  (GC的主力部分

GC一定是一次回收一个完整的对象,不能回收半个对象(一个对象有10个成员,肯定是把10个成员的内存都回收了,而不是只回收一部分)

GC的流程

GC的流程,主要是两个步骤。1)找到谁是垃圾     2)释放对应的内存

找到谁是垃圾

一个对象,什么时候创建,时机往往是明确的。但是什么时候不再使用,时机往往是模糊的。在编程中,一定要确保,代码中使用的每个对象,都得是有效的,不能出现“提前释放”的情况。

因此判定一个对象是否是垃圾,判定方式是比较保守的。

此处引入了非常“保守”的,一定不会误判的做法(可能回释放的不及时)。判定某个对象,是否存在引用指向它。

在java中,使用对象,都是通过引用的方式来使用的。如果没有引用指向这个对象,意味着这个对象注定无法在代码中被使用。就可以视为是垃圾了。

如何判定,某个对象是否有引用指向呢?

1)引用计数(不是JVM采取的方案,而是Python/PHP的方案)

会在为new 对象开辟内存空间时,额外开辟一个计数器,每当对象多一个引用,计数器+1。当计数器为0时,即可回收对象。

这种方法存在两个缺陷:

1、消耗额外的存储空间 

如果对象比较大,浪费的空间还好,对象比较小并且对象数目多,空间浪费就多了。

2、存在“循环引用”的问题

 当执行 a = null  b = null 时,此时这两对象相互指向对方,导致两个对象的引用计数,都为1(不为0,不是垃圾)但是你外部代码,也无法访问到这两对象。  

2)可达性分析(是JVM采取的方案)

可达性分析是java采用的做法,解决了空间和循环引用的问题,但是付出了时间上的代价。核心思想是“遍历”,JVM把对象之间的引用关系,理解成了一个“树形结构”。JVM就会不停的遍历这样的结构,把所有能够遍历访问到的对象标记成“可达”,剩下就是“不可达”。

这些树的根结点是怎么确定的?

Java代码中,你所有的

1)栈上的局部变量,引用类型的,都是GC roots

2)常量池中,引用的对象

3)方法区中的静态成员

都是一棵树的根结点。JVM就会周期性的对这所有的树进行遍历,不停的标记可达,也不停的把不可达的对象干掉。

具体树是否复杂,都取决于实际代码的实现。

由于可达性分析,需要消耗一定的时间,因此,java的垃圾回收,没法做到“实时性”。只能周期性进行扫描(JVM提供了一组专门的负责GC的线程,不停的进行扫描工作)

释放垃圾的策略

1、标记-清除

直接把标记为垃圾的对象对应的内存释放掉  (简单粗暴)

这样的做法会存在“内存碎片”问题。指空闲内存被分成一个个的碎片了,后续很难申请到连续的大的内存。并不实用。

2、复制算法

将内存空间分成两块,要释放某一块内存空间时,将无需删除的数据提前复制到另一块内存中。

这种做法空间浪费太多了。如下图删除1、3、5:

3、标记-整理

将无需删除的部分向前搬运,覆盖掉要删除的数据。如删除2、4、6

这种方法能解决空间利用率问题,但是时间开销更大。

JVM中实际采取的方案是综合上述方案,更复杂的策略。分代回收。也就是分情况讨论,根据不同的场景和特点选择合适的方案。根据对象的年龄(经历GC周期性扫描的轮次)来讨论,GC有一组线程,回对内存进行周期性扫描。某个对象经历了一轮GC之后,还是存在,没有成为垃圾,年龄就+1。

JVM堆区的结构如下:

分代回收的流程:1)把新创建的对象,放到伊甸区中。

2)伊甸区中,大部分的对象,生命周期都是比较短的,第一轮GC到达的时候,就会成为垃圾。只有少数对象能活过第一轮GC。

3)伊甸区 -> 生存区    通过复制算法。(由于存活对象很少,复制开销也很低,生存空间也不必很大)

4)生存区 -> 另一个生存区    通过复制算法。每经过一轮GC,生存区中都会淘汰掉一批对象,剩下的通过复制算法,进入到另一个生存区(进入另一个生存区的还有从伊甸区里进来的对象),存活下来的对象,年龄+1.

5)生存区 -> 老年代   某些对象,经历了很多轮GC,都没有成为垃圾,就会复制到老年代。

老年代的对象,也是需要进行GC的,但是老年代的对象生命周期都比较长,就可以降低GC的扫描频率。

以上,关于JVM的垃圾回收机制,希望对你有所帮助。

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

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

相关文章

Codeforces Round 946 (Div. 3) A~G

A.Phone Desktop (枚举) 题意: 小 A A A的手机有一个桌面(或称启动器)。桌面可以由多个屏幕组成。每个屏幕表示为大小为 5 3 5 \times 3 53 的网格,即五行三列。 有 x x x 个应用程序的图标大小为 1 1 1 \times 1 11 个单…

学前基础知识

1、Java版本: 1995年发布第一个版本,创始人gosling。 可知, JAVA8 和 JAVA11 为长期版本,其他均非长期版本,因此主流都在用 JAVA8 或 JAVA11。 2、Java技术体系平台: 3、Java重要特点 ①Java语言是面向对象…

【IDEA】Redis可视化神器

在开发过程中,为了方便地管理 Redis 数据库,我们可能会使用一些数据库可视化插件。这些插件通常可以帮助你在 IDE 中直观地查看和管理 Redis 数据库,包括查看键值对、执行命令、监视数据库活动等。 IDEA作为IDE界的Jenkins,本身自…

游戏联运的挑战与核心关键点

​游戏联运一个看似充满机遇与挑战的行业,吸引了很多创业者的加入。然而,真正踏入这个行业后,许多人会发现,手游代理并非想象中的那么简单。今天,溪谷软件就来和大家聊聊游戏联运是怎么做的,需要注意什么。…

HTTP请求拦截器链

文章目录 HTTP请求拦截器链需求定义写一个Controller方法接口写三个http请求拦截器把拦截器加入到配置中,并且配置拦截规则在postman里面发送请求,看下测试结果是否正确 HTTP请求拦截器链 需求定义 我们写一个包含三个HTTP请求拦截器的拦截器链&#x…

MongoDB数据库(10亿条数据)清理策略: 自动化过期数据删除实战

1、引言 随着应用程序和业务数据的持续增长,有效地管理数据库存储空间成为维护系统性能的关键。在MongoDB这类NoSQL数据库中,定期清理过期数据变得尤为重要,这不仅能释放宝贵的存储资源,还能优化查询性能,确保数据库运…

PS:电子书App自动截图后合成一个PDF文档

说明:有的电子书App不能下载到本地,通过自动截图后合成一个PDF文档来解决! 一、自动截图App 1.安装”免ROOT自动化助手“ 2.创建一个任务 3.编辑任务:根据电子书的操作顺序制定,400次就是书籍页数(次数一…

【Jmeter】性能测试之压测脚本生成,也可以录制接口自动化测试场景

准备工作-10分中药录制HTTPS脚本,需配置证书 准备工作-10分中药 以https://www.baidu.com/这个地址为录制脚本的示例。 录制脚本前的准备工作当然是得先把Jmeter下载安装好、JDK环境配置好、打开Jmeter.bat,打开cmd,输入ipconfig,…

Vitis HLS 学习笔记--块级控制协议-ap_ctrl_chain/ap_ctrl_hs/ap_ctrl_none

目录 1. 简介 2. 详细分析 2.1 使用场景区别 2.2 ap_continue 行为详解 2.3 ap_ctrl_chain 行为详解 3. 总结 1. 简介 块级控制协议允许硬件模块表明: 何时可以开始处理数据。何时完成了数据处理。以及何时处于空闲状态,准备接受新的数据输入。 …

这么多不同接口的固态硬盘,你选对了嘛!

固态硬盘大家都不陌生,玩游戏、办公存储都会用到。如果自己想要给电脑或笔记本升级下存储,想要存储更多的文件,该怎么选购不同类型的SSD固态盘呐,下面就来认识下日常使用中常见的固态硬盘。 固态硬盘(Solid State Drive, SSD)作为数据存储技术的革新力量,其接口类型的选…

【深度 Q 学习-01】 Q学习概念和python实现

文章目录 一、说明二、深度 Q 学习概念三、python实现四、结论 关键词:Deep Q-Networks 一、说明 在强化学习 (RL) 中,Q 学习是一种基础算法,它通过学习策略来最大化累积奖励,从而帮助智能体导航其环境。它…

气膜建筑的运营成本解析:高效节能的运作模式—轻空间

气膜建筑以其独特的优势和广泛的应用吸引了大量关注。然而,许多人对其持续吹气的运营成本产生了疑问。实际上,气膜建筑通过智能控制系统和高效的风机管理,大大降低了运营成本。本文将以2000平方米的气膜建筑为例,详细解析其运行成…

Vue3 - 实现一个雨水滴落的动画效果

在 Vue 3 中实现一个雨水滴落的动画效果,可以使用 HTML5 的 <canvas> 元素和 JavaScript 来绘制和控制动画。 以下是一个实现雨水滴落效果的示例: 创建一个 Vue 3 项目 首先,确保你已经创建了一个 Vue 3 项目。如果还没有,可以使用 Vue CLI 来创建: vue create r…

2024年社会发展、人文艺术与文化国际会议(ICSDHAC 2024)

2024年社会发展、人文艺术与文化国际会议&#xff08;ICSDHAC 2024&#xff09; 会议简介 2024年国际社会发展、人文、艺术和文化会议&#xff08;ICSDHAC 2024&#xff09;将在广州举行。会议旨在为从事社会发展、人文、艺术和文化研究的专家学者提供一个平台&#xff0c;分…

字符串操作:写一个方法,实现字符串的反转,如:输入abc,输出cba

import java.util.Scanner; public class Test_A15 {public static void main(String[] args){String strA"";System.out.println("请输入一串字符串:");Scanner scannernew Scanner(System.in);strAscanner.next();Test_A15 T15new Test_A15();String re…

leetCode.86. 分隔链表

leetCode.86. 分隔链表 题目思路&#xff1a; 代码 class Solution { public:ListNode* partition(ListNode* head, int x) {auto lh new ListNode(-1), rh new ListNode(-1);auto lt lh, rt rh;for(auto p head; p; p p->next ) {if(p->val < x) {lt lt->…

Midjourney保姆级教程(五):Midjourney图生图

Midjourney生成图片的方式除了使用文字描述生成图片外&#xff0c;还有“图生图”的方式&#xff0c;可以让生成的图片更接近参考的图片。 今天我们来聊聊“图生图”的方式。 一、模仿获取propmt 很多时候&#xff0c;我们不知道画什么内容的图片&#xff0c;大家可以关注内…

SRS视频服务器应用研究

1.SRS尝试从源码编译启动 1.1.安装ubuntu 下载镜像文件 使用VMWare安装&#xff0c;过程中出现蓝屏&#xff0c;后将VM的软件版本从15.5升级到17&#xff0c;就正常了。 1.2.更新ubuntu依赖

第二十四章多栏布局解决方案(什么是自适应?/)

什么是自适应? 指能使网页自适应显示在不同大小终端设备上新网页设计方式及技术.简单的来说自适应就是让同一个页面自动适应不同大小的设备&#xff0c;从而解决为不同设备提供不同版本的页面问题。 1&#xff0e;两列自适应 两列自适应布局是指左侧固定宽度&#xff0c;右…

低代码开发与人工智能技术在商品推荐系统中的应用

引言 低代码开发和人工智能技术的背景和重要性 随着数字化转型的深入&#xff0c;企业在信息技术领域面临着前所未有的挑战和机遇。快速变化的市场需求、日益复杂的技术环境以及高度竞争的商业环境&#xff0c;迫使企业不断寻求高效的开发和运营解决方案。低代码开发平台应运而…