当前位置: 首页 > 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. 逻辑说明: 下拉刷新: 用户向下拖动页面顶部,触发一个事件,刷新当前内容。需…...

Opencv第十一章——视频处理

1. 读取并显示摄像头视频 1.1 VideoCapture类 VideoCapture类提供了构造方法VideoCapture(),用于完成摄像头的初始化工作,其语法格式如下: capture cv2.VideoCapture(index) 参数说明: capture:要打开的摄像头视频。 index:摄像头设备索引。…...

Flutter 3.24 AAPT: error: resource android:attr/lStar not found.

在Android build,gradle下面,添加右边红框的代码: subprojects {afterEvaluate { project ->if (project.plugins.hasPlugin("com.android.application") ||project.plugins.hasPlugin("com.android.library")) {project.androi…...

C++——输入一个2*3的矩阵, 将这个矩阵向左旋转90度后输出。(要求:使用指针完成。)

没注释的源代码 #include <iostream> using namespace std; int main() { int a[2][3]; cout<<"请输入一个2*3的矩阵:"<<endl; for(int i0;i<2;i) { for(int j0;j<3;j) { cin>>a[i][j…...

AI芯片WT2605C赋能厨房家电,在线对话操控,引领智能烹饪新体验:尽享高效便捷生活

在智能家居的蓬勃发展中&#xff0c;智能厨电作为连接科技与生活的桥梁&#xff0c;正逐步渗透到每一个现代家庭的厨房中。蒸烤箱作为智能厨电的代表&#xff0c;以其丰富的功能和高效的性能&#xff0c;满足了人们对美食的多样化追求。然而&#xff0c;面对众多复杂的操作功能…...

详解调用钉钉AI助理消息API发送钉钉消息卡片给指定单聊用户

文章目录 前言准备工作1、在钉钉开发者后台创建一个钉钉企业内部应用&#xff1b;2、创建并保存好应用的appKey和appSecret&#xff0c;后面用于获取调用API的请求token&#xff1b;3、了解AI助理主动发送消息API&#xff1a;4、应用中配置好所需权限&#xff1a;4.1、权限点4.…...

57 长短期记忆网络(LSTM)_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录长短期记忆网络&#xff08;LSTM&#xff09;门控记忆元输入门、忘记门和输出门候选记忆元 (相当于RNN中计算 H t H_t Ht​)记忆元隐状态 从零开始实现初始化模型参数定义模型训练和预测 简洁实现小结练习 长短期记忆网络&#xff08;LSTM&a…...

Linux系统安装教程

Linux安装流程 一、前置准备工作二、开始安装Linux 一、前置准备工作 安装好VMWare虚拟机&#xff0c;并下载Linux系统的安装包&#xff1b; Linux安装包路径为&#xff1a;安装包链接 &#xff0c; 提取码为&#xff1a;4tiM 二、开始安装Linux...

Redis: Sentinel工作原理和故障迁移流程

Sentinel 哨兵几个核心概念 1 ) 定时任务 Sentinel 它是如何工作的&#xff0c;是如何感知到其他的 Sentinel 节点以及 Master/Slave节点的就是通过它的一系列定时任务来做到的&#xff0c;它内部有三个定时任务 第一个就是每一秒每个 Sentinel 对其他 Sentinel 和 Redis 节点…...

通信工程学习:什么是IGMP因特网组管理协议

IGMP&#xff1a;因特网组管理协议 IGMP&#xff08;Internet Group Management Protocol&#xff0c;因特网组管理协议&#xff09;是TCP/IP协议簇中负责组播成员管理的协议。它主要用于在用户主机和与其直接相连的组播路由器之间建立和维护组播组成员关系。以下是关于IGMP协议…...

高效批量导入多个SQL文件至SQL Server数据库的实用方法

当需要批量导入多个SQL文件到SQL Server数据库时&#xff0c;可以通过以下几种方法来实现&#xff1a; 方法一&#xff1a;使用SQLCMD命令行工具&#xff08;亲测可用&#xff09; 准备SQL文件&#xff1a;确保所有的SQL文件都位于同一个文件夹内&#xff0c;并且文件扩展名为…...