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

【JavaEE 初阶(十)】JVM

❣博主主页: 33的博客❣
▶️文章专栏分类:JavaEE◀️
🚚我的代码仓库: 33的代码仓库🚚
🫵🫵🫵关注我带你了解更多进阶知识

在这里插入图片描述

目录

  • 1.前言
  • 2.JVM内存区域划分
  • 3.类加载
    • 3.1双亲委派模型
  • 4.垃圾回收(GC)
    • 4.1垃圾识别
      • 4.1.1引用计数
    • 4.1.2可达性分析
    • 4.2垃圾释放
    • 4.2.1标记释放
    • 4.2.2复制算法
    • 4.2.3标记整理
    • 4.2.4分代回收
  • 5.总结

1.前言

JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统,JVM本省是一个比较复杂的东西,我主要从三个方面进行讲述:内存区域划分,类加载机制垃圾回收算法。

2.JVM内存区域划分

JVM其实就是一个进程,进程在运行过程中,要从操作系统申请资源空间,JVM申请的空间会划分为几个不同的区域,每个区域作用各不相同。这些资源支持了后续Java程序的执行。
在这里插入图片描述
堆区:整个进程只有一份,代码中new出来的对象,对象中的非静态成员变量,放在堆区
栈区:虚拟机栈记录了JAVA代码中的调用关系,java局部变量。
程序计数器:专门用来存储下一条Java指令的地址
元数据:整个进程只有一份,一些辅助性质的,描述性质的属性,我们所写的JAVA代码,各种逻辑运算,会通过javac完成代码转换成字节码,此时这些字节码在程序运行时就会被JVM加载到元数据中,此时当前程序如何执行,做哪些事就按照上述元数据区记录的字节执行。
下列元素n,m,t各在什么区?

class Test{
int n;
static int m;
}
main(){
Test t=new Test();
}

t为局部变量在栈区
new Test在堆区
n是成员变量也在堆中
m是static修饰,类属性在元数据区

3.类加载

类加载就是指JAVA程序运行是,把.class文件从硬盘中读到内存,再进行一系列解析。
类加载大致可以分为5步:
1)加载
把硬盘上的.class文件找到,打开文件读取文件内容
2)验证
确保读到的文件内容是合法的
3)准备
给类申请内存空间,默认值为全0
4)解析
主要针对类中的字符串常量进行处理
例如有一串代码为String s=”hello";s变量存入的是hello的地址,但是再.calss文件中不纯在地址的概率,那么为了就可以给s填一个偏移量。
在这里插入图片描述

5)初始化
把类对象的各个部分的属性进行赋值填充

3.1双亲委派模型

在类加载的时候有一个重要模型就是双亲委派模型,描述了如何找到.class文件。在进行加载操作的时候有一个专门的模块叫做类加载器,默认含有三个
BootstrapClassLoader:负责查找标准库的目录
ExtensionClassLoader:负责查找扩展库的目录
ApplicationClassLoader:负责查找当前项目的代码目录,第三方库目录
上述三个类加载器存在父子关系,类似于二叉树,有一个指针指向父类加载器
在这里插入图片描述
双亲委派工作流程:
1)从ApplicationClassLoader作为入口,开始工作
2)ApplicationClassLoader不会立即搜索自己负责的目录,会把搜索的任务交给自己的父亲
3)进入ExtensionClassLoader,也不会立即搜索自己负责的目录,也会把搜索的任务交给自己的父亲
4)进入BootstrapClassLoader,不会立即搜索自己负责的目录,也会把搜索的任务交给自己的父亲
5)BootstrapClassLoader发现自己没有父亲节点,此时会真正的搜索负责的目录,如果找到了就执行后续操作,没有找到就返回给孩子
6)ExtensionClassLoader收到父亲的任务以后,会搜索自己负责的目录,如果找到了就执行后续操作,没有找到就返回给孩子
7)ApplicationClassLoader收到父亲的任务以后,会搜索自己负责的目录,如果找到了就执行后续操作,没有找到就返回给孩子,但如果没有孩子就说明类加载失败,抛出ClassNotFoundException

4.垃圾回收(GC)

垃圾回收是回收的内存,其中主要回收的是堆中的内存,栈中的内存在代码块结束以后会自动销毁。那么垃圾回收具体是怎么展开的呢?主要分为垃圾识别和垃圾释放

4.1垃圾识别

判定new出来的对象在后续是否要使用,如果不再使用旧标记为垃圾。
例:

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

当程序执行到}时,t就被释放,此后就不再使用new Test()对象了,就可以标记为垃圾,但如果有些大妈比较复杂,例如

Test t=new Test();
Test m=t;
Test n=m;
Test z=n;

此时就有很多引用指向new Test()对象,就学要确保没有任何一个引用指向这个对象才能标记为垃圾,那么我们怎么知道什么时候没有引用指向它呢?

4.1.1引用计数

当我们创建一个对象时,给每个对象分配一个额外的空间记录当前对象有几个引用。
在这里插入图片描述
每增加一个引用,计数位置+1,每减少一个引用,技术位置-1,如果为0就标记为垃圾
问题一
这样会消耗额外的空间,当我们的对象非常多,但对象的体积非常小,那么久可能导致计数所占的空间就占了所有空间的大部分。
问题二
可能会引起循环引用,那么就永远释放不了资源

class Test{
Test t;
}
Test a=new Test();
Test b=new Test();
a.t=b;
b.t=a;
a=null;
b=null;

在这里插入图片描述
这俩对象不能再使用也释放不了

4.1.2可达性分析

在写代码的时候会定义很多变量,就可以从这些变量作为起点开始遍历,所谓的遍历就是会沿着这些变量的引用类型成员再京一部访问,所有能被访问到的自然不是垃圾
在这里插入图片描述

4.2垃圾释放

4.2.1标记释放

最直接的方法就是把标记为垃圾的直接释放掉:但是这样会生成很多内存碎片,后续如果有类对象再申请空间可能就不够用
在这里插入图片描述

4.2.2复制算法

把一个空间分成两半,假设数据存放于左半边那么把不是垃圾的数据全部赋值到右半再讲左半数据全部释放掉。
灰色为垃圾标记,数字为数据
在这里插入图片描述
在这里插入图片描述
这样总的内存空间减少,且复制的开销也很大。

4.2.3标记整理

在这里插入图片描述
在这里插入图片描述
该方案是把所有的数据依次向前搬运,覆盖掉垃圾区,再把剩下的垃圾进行释放。
虽然这样能解决内存碎片的问题,但搬运的内存开销很大

4.2.4分代回收

JVM中有专门的线程负责周期性扫描,一个对象如果被扫描了一次,年龄就+1,JVM会根据对象年龄的差异,把整个堆分成2部分,新生代,老年代。
在这里插入图片描述
1)当代码中new出一个新的对象,这个对象就是被创建在伊甸区,伊甸区的对象大部分都活不够第一轮,生命周期非常短
2)第一轮GC扫描完成以后,少数伊甸区幸存的对象会通过复制算法拷贝到生存区,在后续GC扫描的时候不仅会扫描伊甸区还会扫描生存区的对象,生存区的大多数对象也会在扫描中被标记为垃圾,少数存活,就会继续通过复制算法拷贝到另一个生存区,每次经历一轮GC年龄就+1.
3)如果这个对象在生存区中经历了若干轮依然在,那么就会把这个对象拷贝到老年区。
4)老年代的对象也会被GC扫描只是频次大大减小
5)对象在老年代结束以后就会释放内存。

5.总结

本篇文章主要JVM内存区域划分,类加载,双亲委派模型,垃圾识别,引用计数,可达性分析,垃圾释放,分代回收等等。

下期预告:MySQL

相关文章:

【JavaEE 初阶(十)】JVM

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ 🚚我的代码仓库: 33的代码仓库🚚 🫵🫵🫵关注我带你了解更多进阶知识 目录 1.前言2.JVM内存区域划分3.类加载3.1双亲委派模型 4.垃圾回收(GC&#xff0…...

【Flutter】AspectRatio组件Card组件按钮组件Wrap组件

🔥 本文由 程序喵正在路上 原创,CSDN首发! 💖 系列专栏:Flutter学习 🌠 首发时间:2024年5月25日 🦋 欢迎关注🖱点赞👍收藏🌟留言🐾 目…...

【IDEA软件应用篇】IDEA基础开发设置和开发快捷键

IDEA是一种集成开发环境,可以运行java代码。 本篇文章你将收获到下面的知识: (1)IDEA如何设置字体大小快捷键 (2)如何解决每次进IDEA时,进去的页面都是上次使用完时的那个页面 (3&am…...

机器学习--数学部分笔记

前言 因为周三要考试,所以数学部分写一下笔记 正文 随机事件和随机实验 条件概率 • 在已知事件 𝐵 发生的条件下,事件𝐴发生的概率称为事件 𝐴 的条件概率,记为𝑃(𝐴|𝐵) 全概率…...

基于springboot的在线宠物用品交易网站源码数据库

基于springboot的在线宠物用品交易网站源码数据库 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了在线宠物用品交易网站的开发全过程。通过分析在线宠物用品交易网站管理的不足,创建了一个计算机管理在…...

【Pytorch】13.搭建完整的CIFAR10模型

项目源码 已上传至githubCIFAR10Model,如果有帮助可以点个star 简介 在前文【Pytorch】10.CIFAR10模型搭建我们学习了用Module来模拟搭建CIFAR10的训练流程 本节将会加入损失函数,梯度下降,TensorBoard来完整搭建一个训练的模型 基本步骤 搭建…...

护目镜佩戴自动识别预警摄像机

护目镜佩戴自动识别预警摄像机是一种智能监测设备,专门用于佩戴护目镜的工人进行作业时,能够自动识别有潜在风险的场景,并及时发出预警信号。该摄像机配备人脸识别和智能预警系统,可以检测危险情况并为工人提供实时安全保护&#…...

keep-alive的使用

Vue中的<keep-alive>组件是前端开发中的一个宝藏功能&#xff0c;它如同时光胶囊般保留组件的状态&#xff0c;让组件在切换时仿佛按下暂停键&#xff0c;再次回来时还能继续播放&#xff0c;极大地优化了用户体验和性能。&#x1f680;✨ 作用 状态保留&#xff1a;当包…...

【Linux】中的常见的重要指令(中)

目录 一、man指令 二、cp指令 三、cat指令 四、mv指令 五、more指令 六、less指令 七、head指令 八、tail指令 一、man指令 Linux的命令有很多参数&#xff0c;我们不可能全记住&#xff0c;我们可以通过查看联机手册获取帮助。访问Linux手册页的命令是 man 语法: m…...

营收净利双降、股东减持,大降价也救不了良品铺子

号称“高端零食第一股”的良品铺子(603719.SH)&#xff0c;正遭遇部分股东的“用脚投票”。 5月17日晚间&#xff0c;良品铺子连发两份减持公告&#xff0c;其控股股东宁波汉意创业投资合伙企业、持股5%以上股东达永有限公司&#xff0c;两者均计划减持。 其中&#xff0c;宁…...

【设计模式】设计模式的分类

通常设计模式的分类有创建型、行为型和结构型。 创建型 常用的有&#xff1a;单例模式、工厂模式&#xff08;工厂方法和抽象工厂&#xff09;、建造者模式。 不常用的有&#xff1a;原型模式。 创建型模式涉及到将对象实例化&#xff0c;这类模式都提供一个方法&#xff0c;将…...

TCP/UDP的连接机制

TCP/UDP的连接机制 TCP的连接机制 TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的协议&#xff0c;提供可靠的、按顺序的数据传输服务。TCP的连接机制包括连接建立、数据传输和连接终止。 1. 连接建立&#xff08;三次握手&#xff09; TCP通过…...

供应链金融模式学习资料

目录 产生背景 供应链金融的诞生 供应链金额的六大特征...

代码随想录-算法训练营day50【动态规划12:最佳买卖股票时机含冷冻期、买卖股票的最佳时机含手续费、股票问题总结】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第九章 动态规划part12● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费 ●总结309.最佳买卖股票时机含冷冻期 本题加了一个冷冻期,状态就多了,有点难度,大家要把各个状态分清,思路才能清晰…...

Dilworth 定理

这是一个关于偏序集的定理&#xff0c;事实上它也可以扩展到图论&#xff0c;dp等中&#xff0c;是一个很有意思的东西 偏序集 偏序集是由集合 S S S以及其上的一个偏序关系 R R R定义的&#xff0c;记为 ( S , R ) (S,R) (S,R) 偏序关系&#xff1a; 对于一个二元关系 R ⊂…...

BUUCTF---web---[BJDCTF2020]ZJCTF,不过如此

1、点开连接&#xff0c;页面出现了提示 传入一个参数text&#xff0c;里面的内容要包括I have a dream。 构造&#xff1a;?/textI have a dream。发现页面没有显示。这里推测可能得使用伪协议 在文件包含那一行&#xff0c;我们看到了next.php的提示&#xff0c;我们尝试读取…...

力扣刷题---2206. 将数组划分成相等数对【简单】

题目描述&#x1f357; 给你一个整数数组 nums &#xff0c;它包含 2 * n 个整数。 你需要将 nums 划分成 n 个数对&#xff0c;满足&#xff1a; 每个元素 只属于一个 数对。 同一数对中的元素 相等 。 如果可以将 nums 划分成 n 个数对&#xff0c;请你返回 true &#xf…...

2461. 长度为 K 子数组中的最大和(c++)

给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和&#xff1a; 子数组的长度是 k&#xff0c;且子数组中的所有元素 各不相同 。 返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件&#xff0c;返回 0 。 子数…...

range for

1. 基于范围的for循环语法 C11标准引入了基于范围的for循环特性&#xff0c;该特性隐藏了迭代器 的初始化和更新过程&#xff0c;让程序员只需要关心遍历对象本身&#xff0c;其语法也 比传统for循环简洁很多&#xff1a; for ( range_declaration : range_expression ) {loo…...

leetcode230 二叉搜索树中第K小的元素

题目 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例 输入&#xff1a;root [5,3,6,2,4,null,null,1], k 3 输出&#xff1a;3 解析 这道题应该是能做出…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...