JVM 虚拟机

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.mzph.cn/pingmian/20716.shtml

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

相关文章

行政工作如何提高效率?桌面备忘录便签软件哪个好

在行政管理工作中,效率的提高无疑是每个行政人员都追求的目标。而随着科技的发展,各种便捷的工具也应运而生,其中桌面备忘录便签软件便是其中的佼佼者。那么,这类软件又如何帮助我们提高工作效率呢? 首先,…

SqlServer还原系统库步骤及问题解决

还原master 需要切换到binn目录 Cd C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Binn 关闭服务 用单用户模式启动 SQL Server 默认实例 sqlservr.exe -m 直接单用户登录 恢复master备份文件 RESTORE DATABASE master FROM DISK E:\dbbak\txic_ke…

react 表格实现拖拽功能

项目背景 : react ant 单纯实现拖拽确实不难 , 我的需求是根据后台接口返回 , 生成对应的父子表格 , 并只可以拖拽子的位置 , 如图 后台返回的数据结构 (pid为0说明是父 , 子的pid等于父的id , 说明是父的子) 1 , 我先转成了树形结构且自己加上了key (注意 : key一定得是唯一的…

Resilience4j结合微服务出现的异常

Resilience4j结合微服务出现的异常 1、retry未生效 由于支持aop&#xff0c;所以要引入aop的依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>2、circ…

6. C++通过fork的方式实现高性能网络服务器

我们上一节课写的tcp我们发现只有第一个与之连接的人才能收发信息。他又很多的不足 高性能网络服务器 通过fork实现高性能网络服务器 我们通过fork进行改装之后就可以成百上千的用户进行连接访问&#xff0c;对于每一个用户来说我们都fork一个子进程。让后让每一个子进程都是…

人大金仓数据库大小写不敏感确认

1、图形化确认(管理—其他选项—预设选项) 2、命令行确认 # ksql -p 54321 -U system test # show enable_ci; 查看是否大小写敏感&#xff0c;on表示大小敏感&#xff0c;off表示大小写不敏感&#xff0c;使用某些项目的时候&#xff0c;需要设置数据库大小写不敏感&#…

全网唯一:触摸精灵iOS版纯离线本地文字识别插件

目的 触摸精灵iOS是一款可以模拟鼠标和键盘操作的自动化工具。它可以帮助用户自动完成一些重复的、繁琐的任务&#xff0c;节省大量人工操作的时间。但触摸精灵的图色功能比较单一&#xff0c;无法识别屏幕上的图像&#xff0c;根据图像的变化自动执行相应的操作。本篇文章主要…

【TB作品】msp430f5529单片机墨水屏,口袋板,显示温度和万年历,tmp421温度,RTC时间

文章目录 一、部分程序二、展示三、全部代码下载 一、部分程序 int main(void) {WDTCTL WDTPW | WDTHOLD; //关闭看门狗init(); //屏幕初始化InitIIC(); //I2C初始化TMP_Init(); //tmp421初始化SetupRTC();_EINT();while (1){} }#pragma vectorRT…

ES升级--04--SpringBoot整合Elasticsearch

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 SpringBoot整合Elasticsearch1.建立项目2.Maven 依赖[ES 官方网站&#xff1a;https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.8/index.html](…

Wireshark Lua插件入门

摘要 开发中经常通过抓包分析协议&#xff0c;对于常见的协议如 DNS wireshark 支持自动解析&#xff0c;便于人类的理解&#xff0c;对于一些私有协议&#xff0c;wireshark 提供了插件的方式自定义解析逻辑。 1 动手 废话少说&#xff0c;直接上手。 第一步当然是装上wiresh…

人工智能学习笔记(2):认识和安装Stable Diffusion

人工智能学习笔记&#xff08;2&#xff09;&#xff1a;认识和安装Stable Diffusion 文章目录 人工智能学习笔记&#xff08;2&#xff09;&#xff1a;认识和安装Stable DiffusionStable Diffusion的起源和发展历程Stable Diffusion的应用场景基本原理文本到图像的转换过程潜…

KIBANA的安装教程(超详细)

前言 Kibana 是一个开源的基于浏览器的可视化工具&#xff0c;主要用于分析和展示存储在 Elasticsearch 索引中的数据。它允许用户通过各种图表、地图和其他可视化形式来探索和理解大量数据。Kibana 与 Elasticsearch 和 Logstash 紧密集成&#xff0c;共同构成了所谓的 ELK 堆…

【Linux】 深入讲解自动化构建工具

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Linux一系列的文章&#xff08;质量分均在93分 以…

【计算机毕设】基于SpringBoot的教师工作量管理系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 随着高校规模的扩大和教学任务的增加&#xff0c;教师的工作量管理变得越来越复杂和重要。传统的教师工作量管理方式效率低下&#xff0c;容易出错&…

【Unity知识点详解】Addressables的资源加载

今天来简单介绍一下Addressables&#xff0c;并介绍一下如何通过AssetName加载单个资源、如何通过Label加载多个资源、以及如何通过List<string>加载多个资源。由于Addressables的资源加载均为异步加载&#xff0c;所以今天给大家介绍如何使用StartCoroutine、如何使用As…

安装pytorch深度学习模型时要知道自己的电脑显卡是否支持CUDA

安装pytorch深度学习模型时要知道自己的电脑显卡是否支持CUDA&#xff0c;如何知道自己的显卡是否支持呢&#xff1f;可以去下面的网站&#xff0c;打开后就可以见到如下图所示&#xff1a; CUDA | 支持的GPU | GeForce (nvidia.cn)

[数据集][目标检测]脑溢血检测数据集VOC+YOLO格式767张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;767 标注数量(xml文件个数)&#xff1a;767 标注数量(txt文件个数)&#xff1a;767 标注类别…

【传知代码】基于知识引导提示的因果概念提取(论文复现)

前言&#xff1a;在当今信息爆炸的时代&#xff0c;我们被海量的数据所包围&#xff0c;然而&#xff0c;这些数据中的真正价值往往隐藏在深层的因果关系之中。无论是科学研究、商业决策&#xff0c;还是日常生活中的选择&#xff0c;理解并准确把握事物之间的因果关系&#xf…

Navicat Premium 16.01 下载、安装教程

Navicat Premium 16下载与安装教程 目录 Navicat Premium 16下载与安装教程前言安装步骤同意协议选择安装目录桌面快捷方式安装正在安装安装完成 步骤下载方式 前言 数据库管理用Navicat更加方便&#xff0c;可视化效果更好&#xff0c;今天给大家带来2022 Navicat Premium 16…

【thinkphp问题栏】tp5.1重写URL,取消路径上的index.php

在Apache运行thinkphp5.1时&#xff0c;发现系统默认生成的.htaccess不生效。 首先先查看怎么修改伪静态 1、修改Apache的配置文件 在Apache的安装目录下&#xff0c;打开config/httpd.conf。 搜索rewrite.so&#xff0c;将前面的#删掉&#xff0c;表示开启URL重写功能 2、…