JVM的垃圾回收机制(GC机制)

在Java代码运行的过程中,JVM发现 某些资源不需要再使用的时候,就会自动把资源所占的内存给回收掉,就不需要程序员自行操作了。“自动回收资源”就是JVM的“垃圾回收机制”,“垃圾回收机制”也称"GC机制"

对于Java代码来说,"垃圾回收机制"的回收对象就是"堆"上的对象。因为"栈"上的局部变量,跟随栈帧的生命周期,一个方法执行结束,栈帧销毁,内存也就释放了;"方法区"中的静态变量,跟随着"类"的生命周期,因此静态变量是在程序运行期间始终存在的,无需释放。那么"垃圾"就是 "堆"中的对象。

垃圾回收机制可以分为两大步骤:"找垃圾""回收垃圾"

1. 找垃圾

"找垃圾"有两种方式,分别是 引用计数(python的方式) 和 可达性分析(Java的方式)。

1.1 引用计数

对于一个new出来的对象,会单独安排一块内存空间 来保存一个计数器。这个计数器 就用来描述当前这个对象 有几个引用指向它。当计数器为0时,也就意味着没有引用指向这个对象了,那么这个对象就是"垃圾"了。

1.2 可达性分析

在Java代码运行的过程中,会有一个或一组扫描线程周期性地扫描代码中的所有对象。这个扫描线程,会从一些特定的对象出发,尽可能地进行遍历访问,把所有能够访问到的对象 标记为 可达。反之,经过扫描之后,没有被标记的对象,就是"垃圾"了。可达性分析 是周期性地进行,会消耗一定地系统资源。

2. 回收垃圾

2.1 标记清除

把找到的"垃圾"对象直接释放掉,这就是标记清除的回收方式。这种方式并不好,因为这样的回收垃圾的方法会导致内存中有很多的内存碎片。随着程序的运行,内存碎片会越来越多,这就会导致后续申请内存空间时非常困难。回收垃圾的目的本就是为了释放内存空间,从而让其它进程申请到内存空间,但这种释放内存的方式并没有达到想要的效果。

如下图,虽然此时内存中共有3MB的空闲内存,但都不是连续的,因此其它进程只能申请到小于等于1MB的内存。

2.2 复制算法 

复制算法是对"标记清除"方式的优化,申请到内存之后,只使用内存的一半存储有效对象。出现有内存碎片时,就将有效对象归类到一起,也就是把有效对象拷贝到 存储有效对象的一半内存中,然后再将另一半内存进行释放。

复制算法能够防止出现内存碎片,但这个方式的内存利用率不高,且如果有效对象很多,拷贝的成本就很大了,效率太低。 

2.3  标记整理

标记整理 则是对 标记清除 和 复制算法 的优化,当内存中出现内存碎片时,则会将有效对象拷贝到空闲的内存中,将其覆盖,类似于顺序表删除元素的操作,这样就可以避免内存碎片了。但也涉及到了同样的问题,当需要拷贝的对象太多时,也会有很大的内存开销

2.4 分代回收

JVM在回收垃圾时,采用的方式一般就是 “分代回收”。此方法则是将堆区 划分为 两个区域,分别是"新生代""老年代"。"新生代"区域又划分为两个区域,分别是"伊甸区" 和 "幸存区",幸存区被划分为两块大小相同的区域。

刚创建出来的对象都会出现在"新生代"区域,“GC扫描线程” 会对 新生代区域的对象进行扫描。虽然从 对象的诞生 到 第一轮可达性分析扫描的过程 不会间隔较长时间,但在这段时间里,大部分对象都会成为"垃圾"。因为,这段时间对于程序而言,已经是挺长的时间了,在这个时间段中,对象的引用很快就会随着方法的执行完毕就销毁了,那么这些对象就会成为"垃圾"了。

经过一轮扫描之后,幸存下来的对象就会被拷贝到"幸存区"的一半区域中"伊甸区"的内存就可以整体释放了。虽然这个过程涉及到了拷贝对象的操作,但一般拷贝的对象并不多,因此内存开销是可承受的。GC扫描线程会在后续的扫描过程中,去扫描"幸存区"中的对象。如果幸存区中的对象经过一轮扫描后仍在存在,则会把这个对象拷贝到幸存区的另一半。在幸存区中,每经过一轮扫描,幸存下来的对象都会被拷贝到幸存区的另一半。幸存的对象在幸存区来回拷贝的过程中,会有许多对象被回收掉。如果经过多次扫描幸存区中的某些对象一直存在JVM则会把这些对象放在“老年代”中。相比于“新生代”,“老年代”区域的扫描频率要低,因为JVM认为“老年代”中的对象存活的时间较长。

将整个堆区划分为"新生代"和"老年代",也是为了降低GC扫描的开销。

分代回收则是通过上述的方式来进行垃圾回收,也是综合了 标记清除,复制算法,标记整理的优点,降低内存开销的同时,也避免了内存碎片。

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

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

相关文章

C语言指针进阶_字符指针、指针数组、数组指针、函数指针等的介绍

文章目录 前言一、字符指针二、指针数组三、 数组指针1. 数组名和 & 数组名2. 数组指针3. 数组指针解引用 四、数组指针的使用二维数组的传参说明数组指针使用小测验 五、数组传参和指针传参1. 一维数组传参总结2. 二维数组传参总结3. 一级指针传参4. 二级指针传参 六、函数…

java案例-服务端与客户端(传输对象)

需求 代码 SysUser 用户类Operation 操作类Client 客户端Server 服务端ServerReaderThread 服务端线程类 SysUser 用户类 需要实现Serializable 方便序列化,传输对象 public class SysUser implements Serializable {private String username;private String passwo…

kerberos-hive-dbeaver问题总结

一、kerberos安装windows客户端 1、官方下载地址 http://web.mit.edu/kerberos/dist/ 2、环境变量配置 下载msi安装包,无需重启计算机,调整环境变量在jdk的前面,尽量靠前,因为jdk也带了kinit、klist等命令 C:\Program Files\…

【Node.js工程师养成计划】之原生node开发web服务器

一、使用node创建http服务器 var http require(http);// 获取到服务器实例对象 var server http.createServer() server.listen(8080, function() {console.log(http://127.0.0.1:8080); })server.on(request, function(req, res){console.log(request);res.write(6666666688…

如何利用 GPT 自我提高写作能力

GPT革命:如何用AI技术重新定义写作 介绍 在我们的数字时代,了解自我提高写作的必要性至关重要。 随着 GPT 的兴起,我们正在见证书写的变革时代。 这篇扩展文章深入探讨了 GPT 如何显着提高写作技能。 拥抱未来: 人工智能时代的写…

Maven介绍 主要包括Maven的基本介绍,作用,以及对应的Maven模型,可以对Maven有一个基本的了解

1、Maven介绍 1.1 什么是Maven Maven是Apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。 官网:https://maven.apache.org/ Apache 软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会&…

Elasticsearch实现hotel索引库自动补全、拼音搜索功能

Elasticsearch实现hotel索引库自动补全、拼音搜索功能 在这里边我们有两个字段需要用拼音分词器,一个name字段,一个all字段。 然后我们还需要去实现自动补全,而自动补全对应的字段必须使用completion类型。目前我们酒店里面所有的字段都采用的…

【SpringBoot】00 Maven配置及创建项目

一、Maven配置 1、下载Maven 进入官网下载:Maven – Welcome to Apache MavenMaven – Download Apache Maven 本文以最新版为例,可按需选择版本 Maven – Welcome to Apache Maven 2、解压下载好的安装包 将安装包解压到自己设置的空文件夹中 3、…

AI视频教程下载:构建一个ChatGPT股票配对交易机器人

ChatGPT及其后续版本GPT-4已经开始改变世界。人们对新机会感到兴奋,同时对我们社会可能受到的影响感到恐惧。这门课程结合了两个主题:AI和财务(算法交易)。 你将会学到的: 使用ChatGPT构建一个Python配对交易机器人 …

(Linux)Centos7.*版本安装配置Java环境、Tomcat、Nginx并打包部署SSM框架web系统

一、准备软件与安装包 (一)、必须的软件 1、点击下载Xshell 2、点击下载FileZilla (二)、准备安装包 1、点击下载JDK1.8Linux版本 2、点击下载Nginx 3、点击下载Tomcat 二、关于FileZilla软件的使用说明 (一)、FileZilla软件的打开和说明 (二)、配置服务器地址去连…

理解ROS2的动作

​ 1. 创建一个动作 目标: 在ROS 2软件包中定义一个动作。 1.1 新建包 设置一个 workspace 并创建一个名为 action_tutorials_interfaces 的包: mkdir -p ros2_ws/src #you can reuse existing workspace with this naming convention cd ros2_ws/s…

NLP发展及其详解

一、RNN(循环神经网络) 在这里附上一个很好的笔记 零基础入门深度学习(5) - 循环神经网络 RNN(循环神经网络)的结构特点在于其循环单元的设计,这种设计允许网络在处理序列数据时保持对之前信息的记忆。下面详细解释RNN的结构: 循环单元:RNN的循环单元是网络的核心,它…

基于Springboot的爱心商城系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的爱心商城系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…

[BT]BUUCTF刷题第25天(4.28)

第25天&#xff08;共3题&#xff09; Web [CISCN 2019 初赛]Love Math 打开网站就是一段泄露的源代码&#xff1a; <?php error_reporting(0); //听说你很喜欢数学&#xff0c;不知道你是否爱它胜过爱flag if(!isset($_GET[c])){show_source(__FILE__); }else{//例子 c…

【LeetCode刷题记录】简单篇-70-爬楼梯

【题目描述】 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 【测试用例】 示例1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1.1阶 1阶…

C语言-------实现贪吃蛇小游戏

目录 一、预备知识 1.1 Win32 API介绍 Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外&#xff0c; 它同时也是一个很大的服务中心&#xff0c;调用这个服务中心的各种服务&#xff08;每一种服务就是一个函数&#xff09;&#xff0c;可以帮应用程…

PyVista 3D数据可视化 Python 库 简介

Pyvista是一个用于科学可视化和分析的Python库 &#xff1b;我认为它适合做一些网格数据的处理&#xff1b; 它封装了VTK&#xff08;Visualization Toolkit&#xff09;之上&#xff0c;提供了一些高级接口&#xff0c; 3D数据可视化变得更加简单和易用。 1.安装 pyvista&…

SpringMVC进阶(自定义拦截器以及异常处理)

文章目录 1.自定义拦截器1.基本介绍1.说明2.自定义拦截器的三个方法3.流程图 2.快速入门1.Myinterceptor01.java2.FurnHandler.java3.springDispatcherServlet-servlet.xml配置拦截器4.单元测试 3.拦截特定路径1.拦截指定路径2.通配符配置路径 4.细节说明5.多个拦截器1.执行流程…

LeetCode 150. 逆波兰表达式求值

LeetCode 150. 逆波兰表达式求值 1、题目 题目链接&#xff1a;150. 逆波兰表达式求值 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 ‘’、‘-’、…

如何基于Zookeeper实现注册中心模型?

在分布式系统中&#xff0c;通常会存在几十个甚至上百个服务&#xff0c;开发人员可能甚至都无法明确系统中到底有哪些服务正在运行。另一方面&#xff0c;我们很难同时确保所有服务都不出现问题&#xff0c;也很难保证当前的服务部署方式不做调整和优化。由于自动扩容、服务重…