当前位置: 首页 > news >正文

JVM内存回收机制

目录

1.JVM运行时数据区

2.JVM类加载过程

3.双清委派模型

4.垃圾回收机制(GC)

找出谁是垃圾方案一:引用计数

找出谁是垃圾:方案二,可达性分析

释放垃圾的内存空间

判断垃圾:jvm依据对象的年龄对 对象进行区域划分。

回收垃圾方式:分代回收


1.JVM运行时数据区

JVM运行时数据区域 也叫做:JVM内存布局。

JVM内存布局 和 java内存模型完全不同,JVM内存布局由5大部分组成。

1.堆区(线程共享):程序中所有创建的对象都保存在堆中。JVM最大空间。

2.栈(线程私有)

        1>.java虚拟机栈作用(线程私有):Java虚拟机栈的生命周期 和 线程相同Java虚拟机栈描述了java方法执行的内存模型每个方法在执行时 都会创建一个栈帧,用来储存局部变量方法之间的调用关系动态链接,方法出口等等。

        2>.本地方法栈:与虚拟机栈类似,只不过是给本地方法使用的,本地方法由C++代码编写。

3.程序计数器(线程私有)保存下一条要执行的指令的地址。这里不是CPU寄存器储存的,而是内存空间,指令是java的字节码。不是二进制机器语言。

4.元数据区:(以前叫方法区)保存java代码中涉及类的相关信息。类的static属性。

在一个java进程中,元数据区 和 堆 是只有一份的。即同一个进程中的所有线程共用一份数据

一个java进程中有多个线程,多个线程都有自己的 程序计数器 和 栈。所以每个线程都需要保存自己的“程序计数器” 每个线程都需要记录自己的 调用关系。

检测一下是掌握的怎么样,下面代码中的变量都储存在哪些区域?

public class test4 {static class  Test{private int a;private Test b = new Test();private static int c;private static Test d = new Test();}public static void main(String[] args) {int e = 10;Test f = new Test();}
}

一般地:

局部变量:栈

成员变量:堆

静态成员变量:元数据区(方法区)


2.JVM类加载过程

一个类的生命周期大致为下几个过程。

编写一个java程序 会得到一个 .java文件,在经过javac 编译 就会得到一个 .class文件。

想要运行java 进程,jvm就需要 读取 .class 文件并执行里面的指令。

jvm读取到 .class里面的内容 这个就是类加载。把类 涉及的字节码,从硬盘读取到 内存里。

 加载一个 .claas文件,就会对应创建一个类对象。类对象包含了.class

文件里的各种信息。

类名字,类的属性,类有哪些方法,继承的父类有哪些,实现的接口有哪些....


具体步骤:

1.加载:把 .class 文件找到,然后打开并读取文件的内容。

代码中先见到 类的名字,然后进一步找到对应的 .class 文件(涉及一系列的目录查找过程

2.验证验证读到的 .class 文件的数据是否正确,是否合法。

java标准文档中明确规定 .class 文件的格式是怎么样的。

3.准备:分配内存空间。

根据读取到的内容大小,确定出类对象需要的内存空间,申请这样大小的空间,并把这个空间全部初始化为0.

4.解析:主要针对类中的字符串常量进行处理

java虚拟机 将字符串常量池中的 符号引用 替换为直接引用的过程,也就是初始化常量。

符号引用 其实就是指(字符串常量已经在 .class文件中)文件中 符号的位置,就是偏移量。

直接引用 就是直接保存变量的地址。

5.初始化:针对 类对象 做最终的初始化操作,执行静态成员赋值语句。


3.双清委派模型

操作: 输入一个 类的全限定名(类似于java.lang.String),的到对应的 .class 文件。

属于 jvm加载类中的第一个机制:加载

Bootstrap ClassLoader(加载 标准库中的类)

ExtensionClassLoader(加载 扩展库的类)

ApplicationClassLoader(负责加载第三方库的类)

 

为什么会是这个流程?

核心目的是 方式用户自己写的类把 标准库 或者 扩展库给覆盖掉。

保证 标准库的类是第一位,扩展库的类的是第二位。最后是第三方库的类。

防止程序员 不小心创建一个 和 系统中已有的类重名的类。导致加载的时候覆盖掉了系统的类。


4.垃圾回收机制(GC)

GC 主要存在哪里呢?

栈 和 程序计数器 主要都是跟随线程的结束而结束。

元数据区:类对象涉及到的类加载,一个程序里面吗要加载得类都是有上限的,不会出现无限增长的情况。

所以 堆是GC得主要战区。

垃圾回收,回收内存 都是一对象为维度进行回收的。

GC回收的流程:1.找出谁是垃圾         2.释放垃圾的内存空间

找出谁是垃圾方案一:引用计数

给每个对象分配一个计数器,衡量有多少个引用指向。

每增加一个引用,计数器+1

每减少一个引用,计数器-1,如果计数器为0,此对象就垃圾了需要回收。

此时 对象中的计数器为0,就视为垃圾,需要回收。

上述方案存在两个问题:

1.消耗额外空间去 储存计数器

假设Tets类,只有一个int(4字节)成员,那么就要花2个字节储存计数器,内存多用了 50%

2.引用计数可能会导致“循环引用”,使得上述判定出错。

这种情况就是最后 这俩对象计数器都不是0,都不能被释放。


找出谁是垃圾:方案二,可达性分析

用时间换取空间。

JVM中专门搞了一波周期性的线程,扫面代码中的所有对象,判定某个对象是否“可达”。

对应的,不可达的就是垃圾。

JVM中有所有对象的总名单,按照名单点名,如果没有到的 ,就是垃圾。

JVM中有很多的root根,从这个root开始可以把所有的对象都遍历到。遍历不到但是名单上存在就是垃圾。


释放垃圾的内存空间

1.标记-清除法

如果直接对内存空间进行标记清楚,就有可能导致碎片化的空间无法充分利用。

这样剩下的三个空间就不容易利用了,碎片化的空间不能进行申请连续的空间。

2.复制算法

将被回收后的空间的一分为二,把不是垃圾的对象拷贝到另一侧。确保回收后得到连续的空间

这个算法缺点很明显:

1.内存空间利用率低

2.如果存活下来的对象比较多,复制成本也很大。

3.标记-整理

与标记-清楚类似,但是不一样的是后续并不是直接回收对象,而是让所有的存活对象都向前移动,最后直接清理掉边界标记的就可以了。


4.jvm中真正的解决方案。

判断垃圾:jvm依据对象的年龄对 对象进行区域划分。

如果获得年龄,使用可达性分析 对对象进行扫描,每次描扫后对象的年龄就+1

1.伊甸区比较大,让新创建的对象存放,大多数新创建的对象都活不过第一轮GC,留下来的对象拷贝到幸存区。

2.幸存区,是两个相按照复制算法将存活久对象复制到幸存区,反复多次。幸存区里也会为了保留完整空间进行左右多次复制。

3.一个对象在幸存区多次被拷贝,年龄不断增长,就要拷贝到老年代了。

4.根据经验规律,老年代的对象生命周期都比较长,即便如此也是要进行可达性分析的。

但是老年代的GC频率较低。老年代也需要通过标记整理。


回收垃圾方式:分代回收

分代回收时JVM的GC基本思想方法。

jvm还提供许多“垃圾回收器”对上述的分代回收 作进一步的扩充和具体实现。

CMS涉及理念,把整个GC过程拆分成多个阶段,能和业务线程并发运行的。就尽量并发减少STW时间。

G1把整个内存分成很多快,不同的颜色表示这个一块区域是哪一块(新生代,老年代,幸存区...)

进行GC时不要求一周期就把多个内存都回收,只要回收一部分就好。限制一轮GC的工作量,目的是使STW控制在一定范围,降低STW的影响。

相关文章:

JVM内存回收机制

目录 1.JVM运行时数据区 2.JVM类加载过程 3.双清委派模型 4.垃圾回收机制(GC) 找出谁是垃圾方案一:引用计数 找出谁是垃圾:方案二,可达性分析 释放垃圾的内存空间 判断垃圾:jvm依据对象的年龄对 对象…...

中国身份证号码校验

题目描述 第二届河南省最美教师评选开始了,每一位同学都可以投票选出你支持的人选,但是为了防止刷票,必须通过身份验证才可投票。负责投票平台后台的老大爷希望你能帮他验证身份证号的合法性,防止那些熊孩子随意刷票,…...

【Kubernetes】常见面试题汇总(五十四)

目录 120.创建 init C 容器后,其状态不正常? 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题,即 “ 汇总(一)~(二十二)” 。 题目 69-113 属于【Kubernetes】的生产…...

不懂外语也能无障碍交流?探索4款超好用中英翻译工具

嘿,各位外贸流程的小伙伴们,今儿咱们来聊聊那些翻译神器,看看它们在中英文互译这条路上,是怎么给我们这些天天跟洋文打交道的哥们儿姐们儿减轻负担的。我亲身体验了福昕翻译在线、福昕翻译大师、海鲸AI翻译还有腾讯翻译君&#xf…...

C++ WebDriver扩展

概述 WebDriver协议基于HTTP,使用JSON进行数据传输,定义了client与driver之间的通信标准。无论client的实现语言(如Java或C#),都能通过协议中的endpoints准确指示driver执行各种操作,覆盖了Selenium的所有功…...

WeChat_DevTools 断点调试方法总结

新建工程,以小程序 login 调试为例,代码如下: // 登录wx.login({success: res > {// 发送 res.code 到后台换取 openId, sessionKey, unionIddebugger;resThis this;wx.showModal({title: 登录成功,content: res.code res.code,comple…...

水波荡漾效果+渲染顺序+简单UI绘制

创建场景及布置 创建新场景Main,在Main场景中创建一个plane物体,命名为WaterWavePla,具体数值及层级面板排布如下: 编写脚本 创建一个文件夹,用于存放脚本,命名Scripts,创建一个子文件夹Effect,存放特效相关脚本,创建…...

深度学习中的结构化概率模型 - 使用图来描述模型结构篇

序言 在深度学习的探索之路上,结构化概率模型以其独特的视角和强大的表达能力,成为了研究复杂数据关系的重要工具。这一模型的核心在于其巧妙地利用图来描述模型结构,将随机变量间的复杂交互关系可视化、结构化。图的引入,不仅为…...

C语言中的栈帧

------------------------ | 局部变量区 | | (根据变量声明而变化) | ------------------------ | 参数区 | | (根据函数原型而变化) | ------------------------ | (可选) 保存寄存器区 | | (编译器/架构特定) | -…...

vue数组根据某些条件进行二次切割

原本的一个一维数组首先 1.根据depnm和bed的不同会分成不同的数组 2.在条件1的基础上分割出来的数组如果存在里面有isBgn1的会进行二次分割 比如原数组是[{depnm:1,bed:2,isBgn:0},{}……] 根据条件一会组成一个二维数组得到 [ [①depnm值一致的一个一维数组], [②bed值一…...

Yolov8改进轻量级网络Ghostnetv2

1,理论部分 轻量级卷积神经网络 (CNN) 专为移动设备上的应用程序而设计,具有更快的推理速度。卷积运算只能捕获窗口区域中的局部信息,这会阻止性能进一步提高。将自我注意引入卷积可以很好地捕获全局信息,但会在很大程度上阻碍实际速度。在本文中,我们提出了一种硬件友好…...

【Spring】@RequestMapping、@RestController和Postman

文章目录 1.RequestMapping 注解介绍2. RequestMapping 使用3. RequestMapping 是 GET 还是 POST 请求?GET 请求POST 请求指定 GET/POST 方法类型 2. Postman 介绍1. 创建请求2. 传参介绍1. 普通传参2. form-data3. x-www-form-urlencoded form 表单,对应…...

【深度学习基础模型】回声状态网络(Echo State Networks, ESN)详细理解并附实现代码。

【深度学习基础模型】回声状态网络(Echo State Networks, ESN)详细理解并附实现代码。 【深度学习基础模型】回声状态网络(Echo State Networks, ESN)详细理解并附实现代码。 文章目录 【深度学习基础模型】回声状态网络&#xf…...

Redis的基础认识与在ubuntu上的安装教程

来自Redis的自我介绍 我是Redis,一个中间件,职责是把数据存储在内存上,因此可以作为数据库、缓存、消息队列等场景使用。由于可以把数据存储在内存上,因此江湖人称快枪手 1.redis的功能特性 (1)数据在内存…...

鸿蒙harmonyos next flutter混合开发之ohos工程引用 har 文件

创建鸿蒙原生工程MyApplication。创建flutter module,生成har文件,并且将flutter module中.ohos文件entryability/EntryAbility.ets、pages/Index.ets分别替换MyApplication中的。 # 1. 创建 flutter子模块工程 flutter create -t module my_flutter_…...

react-问卷星项目(5)

实战 路由 路由设计,网址和页面的关系,就是从业务上分析需要哪些页面哪些页面内容可以抽离,业务流程要有入有出增加页面和Layout模版,模版就是抽离页面公共部分,比如都有顶部或者左侧导航,直接上代码&…...

08.useInterval

在 React 应用中,实现定时器功能通常需要使用 setInterval() 和 clearInterval(),这可能会导致代码复杂和难以维护。useInterval 钩子提供了一种声明式的方法来实现定时器功能,使得定时器的管理更加简单和直观。这个自定义钩子不仅简化了定时器的使用,还解决了一些常见的定…...

【Android 源码分析】Activity生命周期之onDestroy

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…...

增强现实中的物体识别与跟踪

增强现实(AR)中的物体识别与跟踪是实现虚拟内容与现实世界无缝融合的关键技术。以下是该领域的主要技术和方法概述: 1. 物体识别 1.1 特征提取 SIFT、SURF、ORB:传统的特征提取算法用于识别图像中的关键点并生成描述符&#xf…...

移动端实现下拉刷新和上拉加载(内含案例)

在前端开发中,上拉加载和下拉刷新常用于实现内容的动态加载,尤其在移动端的应用中。下面我将提供一个简单的示例和逻辑说明。 1. 逻辑说明: 下拉刷新: 用户向下拖动页面顶部,触发一个事件,刷新当前内容。需…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨‍&#x1f…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...