JVM 虚拟机

news2025/2/23 4:12:00

JVM 是 Java Virtual Machine 的简称,意为 Java 虚拟机,虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。 常见的虚拟机有:JVM、VMwave、Virtual Box等。JVM 是一台被定制过的现实当中不存在的计算机;

一、JVM 执行流程

JVM 是 Java 运行的基础,也是实现一次编译到处执行的关键;程序在执行前,首先要将 Java 代码(.java 文件)编译为字节码(.class 文件),JVM 把编译后的字节码通过类加载器(ClassLoader)—— 把文件加载到内存中的 —— 运行时数据区(Runtime Data Area),而字节码文件是 JVM 的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解释器 —— 执行引擎(Execution Engine)将字节码翻译为底层系统指令再交给 cpu 去运行,而这个过程需要调用其他语言的接口 —— 本地库接口(Native Interface)来实现;

即 JVM 主要通过以下四部分来执行 Java 程序;

类加载器,运行时数据区,执行引擎,本地库接口;

二、JVM 内存区域划分

一个运行起来的 Java 进程,需要从操作系统中申请一块内存区域;

JVM 运行时数据区域也叫内存区域,由以下 5 大部分组成:

1. 方法区 / 元数据区(线程共享)

用来存储被虚拟机加载的类信息、常量池、静态变量、即时编译器编译后的代码等数据;

常量池存放字面量和符号引用:

字面量:字符串常量(JDK 8 移动到了堆中),final 常量,基本数据类型的值;

符号引用:类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符;

2. 堆区(线程共享)

程序中创建的所有对象都在保存在堆中,堆里面分为两个区域:新生代和老年代,新生代放新建的对象,当新生代的对象经过一定 GC 次数之后还存活的对象会放入老年代

3. 虚拟机栈(线程私有)

Java 虚拟机栈的生命周期和线程相同,Java 虚拟机栈描述的是 Java 方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息;

1)局部变量表:存放了编译器可知的各种基本数据类型(8 大基本数据类型)、对象引用,局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在执行期间不会改变局部变量表大小;简单来说就是存放方法参数和局部变量

2)操作栈:每个方法会生成一个先进后出的操作栈;

3)动态链接:指向运行时常量池的方法引用;

4)方法返回地址:PC 寄存器的地址;

4. 本地方法栈(线程私有)

本地方法栈和虚拟机栈类似,本地方法栈是给本地方法(用 native 关键字修饰,在 JVM 内部通过 C++ 实现)使用的,即存放了 JVM 内部 C++ 方法的调用关系

5. 程序计数器(线程私有)

用来记录当前线程执行的行号的,程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器;

三、类加载过程

一个类的生命周期如下:

其中前五步都属于类加载的过程;

1. 加载 

根据全限定类名找到该类的字节码文件,并在内存中生成一个代表这个类的 java.lang.Class对象,作为方法区这个类的各种数据的访问入口;

2. 验证

字节码文件是一个二进制格式的文件,需验证当前字节码格式是否符合 Java 虚拟机规范的全部要求,保证字节码中信息被当作代码运行后不会危害虚拟机自身的安全;

3. 准备

为类对象分配内存空间,但并不赋值(真正初始化赋值是在初始化阶段);例如下面的代码:

public static int num = 100;

这个阶段之后,num 的值为 0,而非 100;

但如果是 static final 修饰的基本数据类型的直接赋值方式,或 String 类的直接赋值方式,则会直接在该阶段初始化并赋值;例如

public static final int num = 100;

public static final String str = "abc";

此时 num 的值就是 100,str 的值为 "abc"; 

4. 解析

针对类对象中包含的字符串常量进行初始化操作;

String s = "abc";

s 的初始化语句,会先被设置为一个 "文件的偏移量",当类真正被加载到内存时,再把偏移量替换为真正的内存地址,这个过程也称为将符号引用替换为直接引用; 

5. 初始化

Java 虚拟机真正开始执行类中编写的 Java 程序代码,真的类对象进行初始化,加载父类包括类对象的各个属性,static 成员,静态代码块;

会导致类的初始化的情况

  1. 首次访问这个类的静态变量或静态方法时(由于 main 方法是程序的入口方法,并且main 方法是 static 的,所以 main 方法所在的类,会被首先初始化,但也遵循第 2 条);
  2. 子类初始化,如果父类还未初始化,会先初始化父类; 
  3. 子类访问父类的静态变量,只会触发父类的初始化;
  4. new 会导致初始化;

不会导致类的初始化的情况: 

  1. 访问类的 static final 静态常量(基本类型和字符型)不会触发初始化;
  2. 类对象.class 不会触发初始化;
  3. 创建该类的数组时不会触发初始化;

四、双亲委派模型

双亲委派模型:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每⼀个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载;(查找类的优先级问题) 

类加载器要做的就是根据给定类的全限定类名(包名+类名,例如 java.lang.String)找到其对应的字节码文件,对应类加载过程中的第一步;

JVM 内置了三个类加载器,分别是

启动类加载器:BootStrap ClassLoader;

扩展类加载器:Extension ClassLoader;

应用程序类加载器:Application ClassLoader;

这三个类由上到下是 "爷,父,子" 的关系,但并不是继承的关系,而是 ClassLoader 中,有一个 parent 属性,指向了它的 "父加载器";

若开发人员想要自己实现一个类加载器,需要继承 java.lang.ClassLoader 抽象类;

由一个类的全限定类名,找该类的字节码文件的过程大致如下:

1)从 Application ClassLoader 作为入口,开始查找,Application ClassLoader 负责搜索项目目录和第三方库目录,但是它不会立即寻找,而是交给它的父亲 Extension ClassLoader;

2)Extension ClassLoader 负责 JDK 中扩展的库的目录,但是它也不会立即寻找,而是交给它的父亲 BootStrap ClassLoader;

3)BootStrap ClassLoader 负责标准库的目录,此时,如果在标准库中找打了,则开始读取该字节码文件,若没有找到,则返回给它的孩子寻找;

若最终 Application ClassLoader 也没有找到该类,则会抛出 ClassNotFoundException

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

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

相关文章

【全开源】防伪溯源一体化管理系统源码(FastAdmin+ThinkPHP+Uniapp)

🔍防伪溯源一体化管理系统:守护品质,追溯无忧 一款基于FastAdminThinkPHP和Uniapp进行开发的多平台(微信小程序、H5网页)溯源、防伪、管理一体化独立系统,拥有强大的防伪码和溯源码双码生成功能&#xff0…

EXCEL多sheet添加目录跳转

EXCEL多sheet添加目录跳转 背景 excel中有几十个sheet,点下方左右切换sheet太耗时,希望可以有根据sheet名超链接跳转相应sheet,处理完后再跳回原sheet。 方案一 新建目录sheet,在A1写sheet名,右键选择最下方超链接…

usock: No such file or directory

在搭建T113的tina系统时,运行ubusd报错,“usock: No such file or directory” rootTinaLinux:/# ifup -a Failed to connect to ubus /sbin/ifup: line 51: /sbin/wifi: not foundrootTinaLinux:/# ubusd usock: No such file or directory因为运行 ubu…

正确的功能可将热晶体管风速计线性化

处理传感器电路输出信号的电路或计算公式必须生成传感器响应的反函数。例如,如果传感器响应是对数函数,则线性化部分的响应必须是指数的。 这项工作首先获取传感器响应的 46 个离散点(参见参考论文中的图 4)。刚开始时&#xff0…

MySQL-Explain使用

MySQL-Explain使用 type列 type列 这一列表示关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行记录的大概范围。 依次从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL 一般来说&…

git 提交

当你不小心在master上改了代码,并且add, commit 之后,想push,发现根本push不了(本来也不能直接将master代码push到远端),而且每次pull远程master的时候都要和本地的master进行merge &#xff0c…

初级软件测试快速入门

文章目录 初级软件测试-测试用例、缺陷报告的认识与使用软件测试简介测试分类模型质量模型测试模型 用例编写的八大要素用例设计方法缺陷 初级软件测试-测试用例、缺陷报告的认识与使用 软件测试简介 什么是软件测试? 使用技术手段验证软件是否满足需求 主流技能 …

【Linux】系统优化:一键切换软件源与安装Docker

引言 在Linux系统安装完成后,进行一些必要的初始化设置是提升系统性能和用户体验的关键。本文将重点介绍两个实用的一键脚本:LinuxMirrors提供的软件源切换脚本和Docker安装脚本。这两个脚本将帮助我们简化配置安装过程。 一键切换软件源脚本 在Linux…

算法人生(20):从“自注意力机制”看“个人精力怎么管”

我们知道在ChatGPT中,Transformer模型扮演着重要的角色。Transformer 模型通过自注意力机制来建模序列中的依赖关系,从而实现对序列数据的处理的。因为传统的循环神经网络(RNN)和卷积神经网络(CNN)在处理长…

【NPS】微软NPS配置802.1x,验证域账号,动态分配VLAN(有线网络续篇)

继上一篇文章中成功实施了有线802.1x验证域账号并动态分配VLAN的策略之后,我们迎来了一个新的目标:在用户验证失败时,自动分配一个Guest VLAN,以确保用户至少能够访问基本的网络服务。这一改进将显著提升网络的灵活性和用户的上网…

此商家的收款功能已被限制,暂无法支付是怎么回事

商家遇到收款功能被限制的情况时,通常是长时间没有交易导致的,还有可能是存在欺诈等风险造成的。不管是什么原因,商家可以按照以下步骤在微信支付商户平台和微信支付商家助手小程序中查看原因并尝试解决问题。 1. 登录微信支付商户平台 首先…

【免费】2021年数学建模国赛C题问题一--基于熵权法和TOPSIS法详细版附Word加代码

各位大佬好 ,这里是阿川的博客,祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,将是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

龙讯旷腾PWmat团队研发的开源机器学习力场PWMLFF升级,新增高效训练NEP模型

近几年来,一种结合了物理学、高性能并行计算和机器学习算法的新的科研范式——AI for science迅速崛起,并为解决精度与尺度无法并存的问题带来了曙光。基于机器学习力场(machine learning force field, MLFF)的分子动力学&#xf…

深度学习_02_卷积神经网络循环神经网络

卷积神经网络 1. 卷积神经网络 神经元存在局部感受区域----感受野 . 第一个卷积神经网络雏形----新认知机 缺点:没有反向传播算法更新权值,模型性能有限 第一个大规模商用卷积神经网络----Lenet-5 缺点:没有大量数据和高性能计算资源。 第一个…

【造化弄人:计算机系大学生真的象当年的高速公路收费员一样吗?】

曾经高速公路的收费员是多么的自豪和骄傲,按照常逻辑,车是越来越多,收费员应该越来越多?但现实情况,大家有目共睹! 不论你的车子怎么跑,只要上高速就要交费,那时候的收费员&#xf…

中国版Wayve决战端到端,等待数据的大力出奇迹

作者 |王博 编辑 |德新 「人工智能的定律只有一个,就是规模定律(Scaling Law),大力出奇迹。端到端是描述方式,更应该去考虑如何去生产更多的自动驾驶合适的数据,来喂养更大更合适的模型,取得更…

django ORM model update常规用法

Django ORM(对象关系映射)提供了一种强大而直观的方式,通过Python类和方法与数据库交互。在Django模型中更新记录是一个常见的任务,可以通过多种方式完成。以下是一些常见的更新记录的方法: 1. 更新单条记录 使用 sa…

Python实现日志的记录

1 日志 1、介绍 日志(Log)是一个记录事件或系统活动的文件或数据集,日志是系统管理员和开发者用于诊断问题、监视系统性能、以及追踪用户活动的关键工具。包含以下: 系统日志:记录操作系统、应用程序、硬件组件等的事…

【工具】windows下VMware17解锁mac安装选项(使用unlocker427)

目录 0.简介 1.环境 2.安装前后对比 3.详细安装过程 3.1 下载unlocker427 1)下载地址 2)下载unlocker427.zip 3)解压之后是这样的 4)复制iso中的两个文件到你本地的VMware的安装目录下 5)复制windows下的所有…