java程序是如何执行的

        我们开发的.java文件也就是源文件在经过了java编译器的编译之后变成了.class文件也就是字节码文件,当jvm在执行过程中用到某个类,而这个类还未被加载到内存中时,会由类加载器负责这个类的加载,整个的加载过程分成五步:加载、验证、准备、解析、初始化。

        加载阶段是由类加载器将这个类的字节码文件加载到内存中,并为这个类创建java.lang.Class对象,这个类的信息会被保存到方法区中。验证阶段是jvm对字节码文件执行字节码规范的验证,只有符合jvm字节码规范的class文件才能被成功加载到内存中,验证阶段是与加载阶段并行的。验证通过之后,进入准备阶段,准备阶段将为类变量分配存储空间,并为其赋予默认的初始值。解析阶段是将文件中的符号引用替换为直接引用,比如对于String str = "China";将str的引用替换为字符串常量池中China这个字符串常量的地址。初始化阶段会为类变量赋予真正的初始值。

        以上五步执行完毕之后,就完成了这个类的加载,这个类就可以执行了,类的执行是由解释器配合着程序计数器完成的,解释器是由jvm提供的,它的作用是将字节码指令解释为本地机器指令执行,而程序计数器是由当前执行的线程提供的,它的作用是在解释器解释执行时,指向下一行将要被执行的字节码指令。线程在被创建的时候,jvm会为它分配栈内存及程序计数器,栈内存包括虚拟机栈和本地方法栈,所以栈内存和程序计数器都是被线程私有的内存区域,方法的执行就是发生在栈内存中的,普通方法在虚拟机栈中执行,native方法在本地方法栈中执行,以虚拟机栈为例来说明一下一次方法的执行过程:

        虚拟机栈内部保存的是一个一个的栈桢,每个栈桢都对应着这个虚拟机栈所属线程中的一次方法调用,每个栈桢从入栈到出栈的过程都对应着一次方法从执行到退出执行的过程,那么虚拟机栈中为什么会有多个栈桢呢?这是因为我们的方法在执行过程中经常又去调用其他方法,而其他方法内部可能又存在着另外一个方法的调用,所以方法的执行过程中存在调用链,而处在调用链上的每一次方法调用都会有一个栈桢与之对应,所以虚拟机栈中会有多个栈桢存在,而处于栈顶的那个栈桢被叫做当前栈桢。栈是一个只能在一端执行操作的数据结构,比如虚拟机栈只能在栈顶执行栈桢的入栈和出栈操作,因此最后入栈的栈桢将最先出栈,而最先入栈的栈桢【比如main方法对应的栈桢】因为被压在了栈底所以最后才能出栈;当前栈桢对应的是当前正在执行的方法,比如:main方法的调用链是:main中调用A方法,A方法中又调用B方法,当main方法开始执行时,会为main方法创建一个栈桢入到虚拟机栈中,当前虚拟机栈中只有这一个栈桢,所以它就是当前栈桢,当调用A方法时,也会为A方法创建一个栈桢入栈,A方法的栈桢被入到了栈顶,所以变成了当前栈桢,而main方法的栈桢被压到了栈底,当调用到B方法时,又为B方法创建了一个栈桢入栈,B方法的栈桢又变成当前栈桢。

        栈桢中保存的是本地变量表、操作数栈、方法的引用信息【或者是叫做方法的出口信息】,本地变量表内部保存的是当前方法的局部变量以及参数的值,操作数栈将配合着方法的执行过程,用于存储方法执行中的中间结果,比如有一个int类型的局部变量a,在方法中要实现这个变量的自增操作a++;在执行这个自增操作时,会将本地变量表中保存的a的值压到操作数栈中,在操作数栈中实现它的自增操作,然后将操作结果再从操作数栈中复制到本地变量表中的a变量上。当当前方法执行到最后一条指令,比如return指令时,也就到了当前栈桢出栈的时候了,随着return指令的执行,当前栈桢出栈,引用当前方法的那个方法所对应的栈桢就变成了当前栈桢;随着被调用的方法对应的栈桢依次出栈,最后main线程对应的栈桢变成了当前栈桢,而随着main方法执行结束,main的栈桢出栈,虚拟机栈中不再有栈桢存在,那么运行在当前线程上的一次方法的整个执行过程也就结束了。

        当然在方法的执行过程中,会有新的对象被不断地创建出来,jvm为这些对象在堆内存或者方法区中分配存储空间,而随着方法的结束,一些对象变成了不会再被使用的垃圾对象,jvm提供了垃圾收集器去回收这些对象,释放它们所占用的内存空间,以免发生内存溢出。jvm在用户线程启动时会自动启动用于垃圾回收的gc线程,这些gc线程会与用户线程并发执行,来回收用户线程执行过程中产生的垃圾,这些gc线程也会随着用户线程的退出而停止执行。

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

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

相关文章

Databend 的安装配置和使用

介绍 Databend 是一个内置在 Rust 中的开源、弹性和工作负载感知的云数据仓库,为 Snowflake 提供了具有成本效益的替代方案,专门对最大的数据集进行复杂分析而设计。 性能: 在存储对象上,能快速进行数据分析。没有索引和分区&a…

linux系统颜色的设置

颜色 颜色控制码 颜色 echo -e "\033[字背景颜色;文字颜色m字符串\033[0m" //设置文本颜色 echo -e "\033[0;32m字符串\033[0m" //设置文本为绿色,背景没有颜色 echo -e "\033[0;$(($RANDOM%730))m字符串\033[0m" //随机生…

【PythonRS】栅格数据/图片位深度(bit)转换

关于栅格数据/图片的位深度(eg.8bit、16bit、32bit)转换之前我就发过一篇文章,【Python&RS】基于GDAL栅格数据/图片位深度(bit)转换。但是最近在使用的时候发现好像效果不行,有时候转换不成功&#xff…

批量转换QQ音乐音频文件格式:从FLAC、OGG到MP3

目录 工具和库批量转换脚本结语 我们经常需要将音频文件从一种格式转换为另一种以满足不同的需求。例如,从QQ音乐中下载的 FLAC格式虽然提供了无损的音质,但文件大小较大,不适合在所有设备上播放。而MP3格式由于其较小的文件大小和广泛的兼容…

创意无限:火星文和变异字体的魅力世界

在互联网的浩瀚星空里,火星文和变异字体如同璀璨的繁星,照亮了网络世界的角落。它们以独特的创意和视觉冲击力,吸引着无数网友的目光。让我们一起走进这个充满创意和想象力的世界,感受火星文和变异字体的无限魅力。 火星文生成器…

软件测试|SQL中的LIKE模糊匹配该怎么用?

简介 在SQL(Structured Query Language)中,LIKE是一种用于模糊匹配的操作符。通过使用LIKE,我们可以根据模式匹配的方式进行数据检索,而不仅仅局限于完全匹配。本文将详细介绍SQL中LIKE操作符的语法、用法以及一些示例…

全志F1C100s Linux 系统编译出错:不能连接 github

环境 Ubuntu 20.04 LTS 64 位虚拟机 开发板:Lichee Pi Nano 源代码:GitHub - florpor/licheepi-nano 问题描述 该源码库使用了 git 子模块的概念,一个库中包含了 u-boot、Linux等代码库。不需要分别编译,一个 make 全搞定 编译时提示错误: >>> linux-hea…

Halcon根据特征值选择区域select_shape

Halcon根据特征值选择区域 关于提取图像的特征,比较常用的一个算子是select_shape算子,它能高效地根据特征提取出符合条件的区域。该算子的原型如下: select_shape (Regions : SelectedRegions : Features, Operation, Min, Max :)参数1和参…

win和linux打印tree命令目录结构命令

win 输入tree: cmd: tree 显示文件夹不显示文件 可以用相对路径:tree .\test_pipreqs 省略.\也可以:tree test_pipreqs 显示文件 上面只显示文件夹未能显示文件。我们继续看下面: cmd: tree [path] [/f] [/a] ----------/f 显示每个文件中文件…

修改 Git 仓库的远程地址

要修改 Git 仓库的远程地址&#xff0c;你可以使用以下命令&#xff1a; 首先&#xff0c;查看当前的远程地址列表&#xff0c;使用命令 git remote -v。如果你想修改已存在的远程地址&#xff0c;可以使用命令 git remote set-url <remote_name> <new_url>。在这…

【论文阅读笔记】Mip-NeRF 360: Unbounded Anti-Aliased Neural Radiance Fields

目录 概述摘要引言参数化效率歧义性 mip-NeRF场景和光线参数化从粗到细的在线蒸馏基于区间的模型的正则化实现细节实验限制总结&#xff1a;附录退火膨胀采样背景颜色 paper&#xff1a;https://arxiv.org/abs/2111.12077 code&#xff1a;https://github.com/google-research/…

【LeetCode】601. 体育馆的人流量

表&#xff1a;Stadium ------------------------ | Column Name | Type | ------------------------ | id | int | | visit_date | date | | people | int | ------------------------ visit_date 是该表中具有唯一值的列。 每日人流量…

Android 项目工程配置签名文件

1. Android签名证书(.keystore) Android平台打包发布apk应用&#xff0c;需要使用数字证书&#xff08;.keystore文件&#xff09;进行签名&#xff0c;用于表明开发者身份。   Android证书的生成是自助和免费的&#xff0c;不需要审批或付费。   可以使用JRE环境中的keyto…

【UML建模】部署图(Deployment Diagram)

1.概述 部署图是一种结构图&#xff0c;用于描述软件系统在不同计算机硬件或设备上的部署和配置情况&#xff0c;以图形化的方式展示系统中组件、节点和连接之间的物理部署关系。 通过部署图&#xff0c;可以清晰地了解系统的物理结构和部署方式&#xff0c;包括系统组件和节…

使用免费工具在 Windows 11/10/8/7 中扩展 C 盘的 3 种方法

越来越多的Windows 10笔记本电脑和台式机使用SSD作为系统盘&#xff0c;这对于提高计算机性能很有用&#xff0c;因为SSD的读写速度要快得多。但另一方面&#xff0c;SSD价格更高&#xff0c;因此比传统机械硬盘体积更小。当然C盘空间不足的可能性更大。在这种情况下&#xff0…

在Docker中安装和配置InfluxDB,设置SSL和密码保护

在Docker中安装和配置InfluxDB&#xff0c;设置SSL和密码保护 引言 InfluxDB是一个开源的时间序列数据库&#xff0c;常用于存储和查询大量时序数据。通过使用Docker&#xff0c;我们可以轻松地部署和管理InfluxDB容器&#xff0c;并配置SSL以及设置用户名和密码进行保护。本博…

45. 跳跃游戏 II(Java)

题目描述&#xff1a; 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到…

四种“栈溢出检测方法”实现分析(2种纯软件、一种纯硬件、一种软硬件结合)

1、两种纯软件的栈溢出检测方法 参考博客&#xff1a;《freeRTOS的栈溢出检测机制》&#xff1b; 2、纯硬件&#xff1a;使用栈限制寄存器 2.1、工作逻辑分析 前提条件&#xff1a;使用满减栈硬件上提供栈限制寄存器&#xff08;用SP_limit表示&#xff09;&#xff0c;可以…

如何将支持标准可观测性协议的中间件快速接入观测

前言 作为一名云原生工程师&#xff0c;如何将支持标准可观测性协议的中间件快速接入观测云呢&#xff1f;答案是只需要三步。 首先&#xff0c;需要确定您要观测的中间件类型。支持标准可观测性协议中间件可通过观测云的 DataKit 采集到中间件的关键指标。有些中间件自带可观…

数据库备份规范

备份方式 1、周期性例行备份 生产数据库例行备份统一使用定时任务备份&#xff0c;备份时间定时到业务低峰期。每天备份一次&#xff0c;保留7天的备份&#xff0c;超过7天的备份包括binlog上传到s3存储上。 2、线上数据库变更前备份。 分为自动变更和手动变更&#xff0c;遵…