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

【JVM】内存区域划分,类加载的过程,.class文件的格式

一个java写的程序,跑起来就得到了一个java进程,而java进程=JVM+上面运行的字节码指令

JVM是「java虚拟机」,负责解释执行java的指令

【JVM内存区域划分】

1.程序计数器(比较小的空间)

作用:保存了下一条要执行的指令的地址

这里“下一条要执行的指令”是Java的字节码(不是CPU的二进制机器语言)

2.堆

JVM上最大的空间,new出来的对象都在堆上

3.栈

栈中所保存的信息,有函数中的局部变量,函数的形参和函数之间的调用关系

4.元数据区

(以前这个地方也叫作“方法区”)

存放Java程序中的指令(最开始写的Java代码,都是在代码中创建一个一个类,然后给这些类编写一些属性和方法,这些方法被JavaC编译,得到了一些字节码指令),指令都包含在类的方法中

它保存了代码中涉及到的,类的相关信息以及类的static属性

在一个java进程中,元数据和堆只有一份,程序计数器和栈,则可能有多份(当一个Java进程中有多个线程时,每个线程都有自己的程序计数器和栈)

线程就代表一个“执行流”,每个线程就需要保存自己的“程序计数器”,每个线程也需要记录自己的调用关系

【栈帧】

如上文所述,栈是用来保存方法之间的调用关系的

举个例子,代码最开始执行时,调用了一个A方法,此时栈中就会产生一个「A方法的栈帧」,A方法的栈帧里面就会保存一些重要的信息(当前方法的入口地址,方法的形参,方法的局部变量,返回之后继续执行的地址等)

方法A在调用过程中,也许还会调用方法B,此时栈中就会产生一个「B方法的栈帧」,这里也会包含了B方法相关的信息,以此类推

当方法执行完毕后,栈帧会被销毁

当调用新的方法时,栈帧会被创建

因此这是根据代码的流程随时创建随时销毁的

【变量所处的区域】

变量a,b,c,d,e,f都属于哪个内存区域?

一个变量处于哪个内存区域,和变量是不是“内置类型”无关,而是和变量的形态有关

局部变量:栈

成员变量:堆

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

因此:

堆:a,b

栈:e,f

元数据区:c,d

【JVM类加载的过程】

一个Java程序对应一个「.java文件」

javac编译后,可以得到一个「.class文件」

文件会处于硬盘上,在运行java进程时,JVM就需要读取.class中的内容,并且执行里面的指令,.class就是类加载,把类涉及到的字节码从硬盘读取到内存中(元数据区中)

读取完后,就会把这个.class中的指令实现为类对象

加载一个.class文件,也就会对应创建一个类对象,类对象中就包含了.class文件中的各种信息

比如:

类名是什么,类中有哪些属性,每个属性名字是什么 每个属性类型是什么,继承的父类是什么,实现的借口有哪些等等

基于类对象,就可以创建出该类的实例,类对象,其实就是“对象”的说明书/蓝本

【类加载的具体步骤(重点掌握)】

1.加载

把.class文件找到,在代码中先见到类的名字,然后进一步的找到对应的.class文件(涉及一系列目录查找的过程) ,然后打开并读取文件内容

2.验证

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

在Java标准文档中,明确定义了.class文件的格式是怎么样的

3.准备

分配内存空间

最终需要得到一个类对象,而这需要内存来存放,因此需要分配内存空间,根据刚才读取到的内容,确定出类对象需要的内存空间,申请这样的内存空间,并且把内存空间中所有的内容,都初始化为0

Java中,创建一个内存空间,都会把这个内存空间 全部设为0,后续再进行进一步的初始化

4.解析

主要针对类中的字符串常量进行处理

Java虚拟机将常量池内的符号引用替换为直接引用(初始化常量)

如图所示,在“”.class 文件”中,会有一个空间对应着“s”这个变量,也会有一个「常量池」区域用来存储“s”中“hello”这个字符串常量

也就是说,s变量中保存了“hello”字符串常量的地址

但是在文件中,并不存在“地址”这样的概念。谈到地址就是“内存”的地址,而文件(硬盘)中没有地址的概念

虽然没有地址,但是可以存储一个类似于地址的「偏移量」(从文件开头到“hello”的距离)这样的概念,用来变相描述这个数据的位置

5.初始化

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

如果当前加载的类还有父类且父类没有被加载过,那么也会对父类进行加载

【双亲委派模型】

是类加载五个步骤中,第一个步骤中里面的一个环节:给定类的全限定名,找到对应的class文件位置

类加载器JVM中,已经内置了一些类加载器,完成上述的“类加载”过程

JVM默认有三个类加载器:

1.BootstrapClassLoader(负责加载标准库中的类)

2.ExtensionClassLoader(负责加载扩展类)

3.ApplicationClassLoader(负责加载第三方库中的类/自己写的代码中的类)

而「双亲委派模型」是因为这三个类有这样的形象关系:

注意,这里不是Java父类子类这样的继承关系,而是类加载器中有一个parent这样的引用来指向父亲

【双亲委派模型的工作流程】

输入:类的全限定名(字符串),类似于java.lang.String

得到:找到对应的class文件

如果最后也没有找到,会抛出异常“ClassNotFoundException”

为什么这么搞?

防止用户自己写的类,把标准库的类给覆盖掉,保证标准库的类,被加载的类优先级是最高的,扩展库其次,第三方库的优先级最低

【.class文件的格式】

【u4】

4个字节的无符号整数,unsigned int

【u2】

2个字节的无符号整数,unsigned short

【magic】

魔幻数字,计算机圈子中约定俗成的做法,二进制文件中,会在开头的若干个字节,设置一个固定的常熟进去,通过这个常数,标识当前这个文件是什么样的文件

【minor_version和major_version】

确保编译时使用的JDK和运行时使用的JDK版本一致

(低版本JDK编译出的文件在高版本JDK中一般可以运行,但高版本在低版本上无法运行)

【access_flags——interface_count】

描述当前这个类涉及的父类信息和接口信息

【fields_count—末尾】

描述类中的属性和方法,以及额外的属性和方法

相关文章:

【JVM】内存区域划分,类加载的过程,.class文件的格式

一个java写的程序,跑起来就得到了一个java进程,而java进程=JVM上面运行的字节码指令 JVM是「java虚拟机」,负责解释执行java的指令 【JVM内存区域划分】 1.程序计数器(比较小的空间) 作用:保存了下一条…...

esp32-camera入门(基于ESP-IDF)

主要参考资料: ESP32-S2 Kaluga camera lcd 示例入门: https://blog.csdn.net/Marchtwentytwo/article/details/121121028 摄像头应用方案常见问题汇总: https://docs.espressif.com/projects/esp-faq/zh_CN/latest/application-solution/camera-application.html …...

react中类式组件与函数式组件的区别

在React中,类式组件(Class Components)与函数式组件(Functional Components)是两种不同的组件定义方式,它们各有特点,适用于不同的场景。以下是它们之间的主要区别: 一、定义与语法…...

【D3.js in Action 3 精译_030】3.5 给 D3 条形图加注图表标签(下):Krisztina Szűcs 人物专访 + 3.6 本章小结

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一部分 D3.js 基础知识 第一章 D3.js 简介(已完结) 1.1 何为 D3.js?1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践(上)1.3 数据可…...

【重学 MySQL】五十六、位类型

【重学 MySQL】五十六、位类型 定义赋值与使用注意事项应用场景 在MySQL数据库中,位类型(BIT类型)是一种用于存储位字段值的数据类型。 定义 BIT(n)表示n个位字段值,其中n是一个范围从1到64的整数。这意味着你可以存储从1位到64…...

Centos7 NTP客户端

目录 1. NTP客户端1.1 安装1.2 启动1.3 同步状态异常1.4 更改/etc/chrony.conf配置文件1.5 同步状态正常 1. NTP客户端 1.1 安装 如果chrony没有安装,可以使用以下命令安装 sudo yum install chrony1.2 启动 启动并设置开机自启 sudo systemctl start chronyd …...

手机号归属地查询-手机号归属地-手机号归属地-运营商归属地查询-手机号码归属地查询手机号归属地-运营商归属地

手机号归属地查询API接口是一种网络服务接口,允许开发者通过编程方式查询手机号码的注册地信息。关于快证签API接口提供的手机号归属地查询服务,以下是一些关键信息: 一、快证签API接口简介 快证签API接口可能是一个提供多种验证和查询服务…...

CoppeliaSim和Matlab建立远程连接教程

CoppeliaSim和Matlab建立远程连接教程 Matlab通过调用CoppeliaSim的远程API和库函数实现远程连接,为实现Matlab和CoppeliaSim的联合仿真做准备。 一、获取并查看版本信息 点击 Help 查看版本信息 使用的CoppeliaSim Edu版本为:4.4.0 位数:64bit 二、拷贝API函数和库文件…...

使用STS以及签名URL临时授权访问OSS资源

本文介绍JAVA如何使用STS以及签名URL临时授权访问OSS资源。 注意事项 由于STS临时账号以及签名URL均需设置有效时长,当您使用STS临时账号生成签名URL执行相关操作(例如上传、下载文件)时,以最小的有效时长为准。例如您的STS临时账…...

Next.js 14 使用 react-md-editor 编辑器 并更改背景颜色

1.简介 react-md-editor是一款markdown编辑器,本文介绍如何在Next.js中使用它。 2.安装 安装命令: npm install uiw/react-md-editor3.MD编辑器 markdown编辑器的使用: "use client" import MDEditor from uiw/react-md-edi…...

【Iceberg分析】Spark与Iceberg集成落地实践(一)

Spark与Iceberg集成落地实践(一) 文章目录 Spark与Iceberg集成落地实践(一)清理快照与元数据配置表维度自动清理元数据文件属性手动清理 清理孤岛文件合并数据文件 清理快照与元数据 配置表维度自动清理元数据文件属性 每一次写…...

【Verilog学习日常】—牛客网刷题—Verilog进阶挑战—VL45

异步FIFO 描述 请根据题目中给出的双口RAM代码和接口描述,实现异步FIFO,要求FIFO位宽和深度参数化可配置。 电路的接口如下图所示。 双口RAM端口说明: 端口名 I/O 描述 wclk input 写数据时钟 wenc input 写使能 waddr input 写…...

【强训笔记】day27

NO.1 代码实现&#xff1a; #include<iostream>using namespace std;int n,m; int main() {cin>>n>>m;long long retn;for(int i0;i<m-1;i)retret*(n-1)%109;cout<<ret<<endl;return 0; }NO.2 思路&#xff1a;bfs遍历实现&#xff0c;dis…...

Nginx06-静态资源部署

零、文章目录 Nginx06-静态资源部署 1、静态资源概述 静态资源&#xff1a;是在Web开发中不经常改变的文件&#xff0c;比如图片、CSS样式表、JavaScript脚本文件等。这些资源通常是预先编译好的&#xff0c;不需要服务器端的动态处理。动态资源&#xff1a;是在Web开发中需…...

MySQL数据库专栏(二)SQL语句基础操作

目录 数据库操作 创建数据库 查看数据库 选择数据库 删除数据库 数据表操作 数据表数据类型 数据表列约束 数据表索引 创建表 查看表 查看表结构 删除表 数据表的增删改操作 …...

【OpenCV 实战】1.手势虚拟拖拽(双手骨骼点识别)

step: 1.opencv 获取视频流 2.在画面上画一个方块 3.通过mediapipe获取手指关键点坐标 4.判断手指是否在方块上 5.若在方块上&#xff0c;方块跟着手指移动 mediapipe网站介绍&#xff1a;Hands - mediapipe (chuoling.github.io) 已上传到GitHub &#xff1a; plumqm/OpenC…...

基于springboot人力资源管理系统源码

项目技术&#xff1a;SpringBoot 运行环境&#xff1a;jdk1.8idea/eclipsemaven3mysql5.6 项目描述&#xff1a; 系统包括&#xff0c;员工管理&#xff0c;奖惩管理&#xff0c;合同管理&#xff0c;薪酬管理&#xff0c;培训管理&#xff0c;绩效评估等功能...

如何使用 Apt-Get 和 Apt-Cache 在 Ubuntu 和 Debian 中管理软件包

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 Apt 是 dpkg 打包系统的命令行前端&#xff0c;也是许多发行版中管理软件的首选方式。它是 Debian 及基于 Debian 的 Linux 发行版…...

Linux系统创建新分区并挂载的方法

一、引言 本文以CentOS为例讲述Linux系统创建新分区并挂载的方法。如下图所示&#xff0c;用fdisk -l命令可以看到该CentOS系统下有一个磁盘/dev/vda&#xff0c;其容量为2199G&#xff0c;即2T。该磁盘有两个分区&#xff1a;vda1和vda2&#xff1a; 用lsblk命令可以查看到磁…...

反射第二弹:用注册器动态注册(用自定义的注解标注的)策略,实现策略模式的设计

目录 引言 设计思路: 代码实现: 标注注解:@StrategyClass 扫描注解:trategyScan 注册器抽象类: 动态策略注册类: AOP类: 总结: 引言 曾经有人问我,假如有一个业务或者数据处理逻辑,会根据甲方客户繁杂的业务需求,而动态变化,该怎么处理,具体怎么实现? 将…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...