java进阶1——JVM

devtools/2025/2/28 0:35:13/

javaJVM_4">java进阶——JVM

1、JVM概述
作用

Java 虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对 应平台上的机器码指令行,每一条 java 指令,java 虚拟机中都有详细定义,如怎么取操 作数,怎么处理操作数,处理结果放在哪儿。

特点:

一次编译到处运行

自动内存管理

自动垃圾回收功能

现在的 JVM 不仅可以执行 java 字节码文件,还可以执行其他语言编译后的字节码文件,是一 个跨语言平台.

在这里插入图片描述

JVM的位置

在这里插入图片描述

JVM 是运行在操作系统之上的,它与硬件没有直接的交互。

在这里插入图片描述

构成部分:
JVM 整体组成可分为以下四个部分:

1.类加载器(ClassLoader)

2.运行时数据区(Runtime Data Area)

3.执行引擎(Execution Engine)

4.本地库接口(Native Interface)

简图:

在这里插入图片描述

详细图:

在这里插入图片描述

各个组成部分的用途

程序在执行之前先要把 java 代码转换成字节码(class 文件),jvm 首先需要 把字节码通过一定的方式 类加载器(ClassLoader) 把文件加载到内存中 的运行时数据区(Runtime Data Area) ,而字节码文件是 jvm 的一套指 令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析 器执行引擎(ExecutionEngine) 将字节码翻译成底层系统指令再交由 CPU 去执行,而这个过程中需要调用其他语言的接口 本地库接口(Native Interface) 来实现整个程序的功能,这就是这 4 个主要组成部分的职责与 功能。

而我们通常所说的 JVM 组成指的是运行时数据区(Runtime Data Area),因为通常需要程序员调试分析的区域就是“运行时数据区”,或者 更具体的来说就是“运行时数据区”里面的 Heap(堆)模块。

Java 代码的执行流程

在这里插入图片描述

在这里插入图片描述

Java 编译器编译过程中,任何一个节点执行失败就会造成编译失败。虽然各个 平台的 java 虚拟机内部实现细节不尽相同,但是它们执行的字节码内容却是一 样的。 JVM 主要任务就是负责将字节码装载到其内部,解释/编译为对应平台上的机器 指令执行。JVM 使用类加载器(Class Loader)装载 class 文件。 类加载完成后,会进行字节码校验,字节码校验通过之后 JVM 解释器会把字节 码翻译成机器码交由操作系统执行。 但不是所有的代码都是解释执行,JVM 对此作了优化,比如 HotSpot 虚拟机, 它本身提供了 JIT(Just In Time)编译器.

JVM 架构模型

Java 编译器输入的指令流基本上是一种基于栈的指令集架构,另一种指令集架构 是基于寄存器的指令集架构.

基于栈式架构的特点

设计和实现更简单,适用于资源受限的系统. 使用零地址指令方式分配,其执行过程依赖于操作栈,指令集更小,编译器容易实 现.不需要硬件支持,可移植性好,更好实现跨平台.

基于寄存器式架构特点:

指令完全依赖于硬件,可移植性差.

性能优秀,执行更高效.

完成一项操作使用的指令更少.

在这里插入图片描述

使用 javap -v class 文件可以将 class 文件反编译为指令集.

所以由于跨平台的设计,Java 指令集都是根据栈来设计的,不同 CPU 架构不同,

所以不能设计为基于寄存器的.

优点是跨平台,指令集小,编译器容易实现.

缺点是性能下降,实现同样功能需要更多的指令.

2、JVM结构-类加载

类加载子系统

在这里插入图片描述

作用:

类加载器子系统负责从文件系统或者网络中加载 class 文件。

主负责加载类, 有执行引擎执行,存放在方法区(元空间)

扮演者的是一个快递员的角色

在这里插入图片描述

  1. class file 存在于硬盘上,可以理解为设计师画在纸上的模板,而最终这个模板 在执行的时候是要加载 JVM 当中来,根据这个模板实例化出 n 个一模一样的实 例.

  2. class file 加载到 JVM 中,被称为 DNA 元数据模板,放在方法区中.

  3. 在.class–>JVM–>最终称为元数据模板,此过程就要有一个运输工具(类加 载器 Class Loader),扮演一个快递员的角色.

类加载过程

在这里插入图片描述

1.加载

根据类的地址,从硬盘上读取类的信息,

将信息读入到方法区,生成Class类的对象

2.链接

验证: 验证字节码文件格式是否是当前虚拟机所支持的文件格式,语法格式

准备: 为静态成员分配默认值(int 默认值0) 注意static final在编译期间赋值

解析: 将字节码中符号引用 替换 成 直接引用

例如: 编写代码 方法1 中调用 方法2 (符号引用)

类加载到内存后把符号的引用地址 换成 内存的地址引用

3.初始化

类什么时候初始化

1 )创建类的实例,也就是 new 一个对象

2)访问某个类或接口的静态变量,或者对该静态变量赋值

3)调用类的静态方法

4)反射(Class.forName(“”))

5)初始化一个类的子类(会首先初始化子类的父类)

类的初始化顺序

先初始化静态的,多个静态的按照从上向下的顺序执行,

如果类有父类,则先初始化父类的静态,然后是子类.

如果是创建对象,先调用父类的构造方法,然后是子类自己的构造方法

类加载器

在这里插入图片描述

站在JVM的角度划分: 启动类加载器(不是java语言写的),

其他类加载(都是java语言写的)

站在开发者的角度:

启动类加载器(引导类加加载器)

这个类加载器使用 C/C++语言实现,嵌套在 JVM 内部.它用来加载 java 核心类

库.

负责加载扩展类加载器和应用类加载器

加载<JAVA_HOME>lib

扩展类加载类器

是由java语言实现的 继承自ClassLoader

负责加载 E:ProgramFilesJavajdk1.8.0_261jrelibext

应用程序类加载器(系统类加载器)

Java 语言编写的,由 sun.misc.Launcher$AppClassLoader 实现.

派生于 ClassLoader 类.

负责加载用户类

用户自定义类加载器(例如tomcat)

双亲委派机制

在这里插入图片描述

类的加载时按需加载,使用时才会加载.

类加载时,加载器都会将类交给父级类加载器加载.

如果所有的父级加载没有找到类,

则一级一级的向下委派查找.

如果都找不到,那么就会抛出异常.

目的: 为了安全考虑 避免了用户自己写的类覆盖了系统中的类.

类的主动使用和被动使用
主动使用会触发类的初始化

new

使用静态变量 静态方法

反射加载类

执行main方法

子类被初始化 父类也会触发初始化

被动使用不会触发了类的初始化

仅仅使用类的静态常量 而且是直接赋字面量的那种

将类作为数组的类型声明使用时不会触发初始化

3、JVM 运行时数据区

堆,方法区(元空间) 主要用来存放数据 是线程共享的.

程序计数器,本地方法栈,虚拟机栈 是运行程序的,是线程私有的.

程序计数器

jvm中的程序计数器不是cpu中的寄存器, 可以理解为计数器.

是一块非常小的内存空间,运行速度是最快的,不会出现内存溢出情况.

作用:记录当前线程中的方法执行的位置. 以便于cpu在切换执行时,记录程序执行的为位置.

在运行时数据区中唯一一个不会出现内存溢出的区域.

本地方法栈

当我们在程序中调用本地方法时,会将本地方法加载到 本地方法栈中执行.

也是线程私有的, 如果空间不够,也会出现栈溢出错误. hashCode();

虚拟机栈

背景: java为了移植性好(跨平台) 所以将运行程序的设计架构为栈结构运行, 而不是依赖于cpu的寄存器架构.

栈是运行时的单位(加载方法运行),

而堆是存储的单位(存储对象的).

作用运行方法 一个方法就是一个栈帧. 栈帧中包含( 局部变量(基本类型,引用地址) 方法地址,返回地址)

栈中的操作 入栈,出栈
栈中异常 StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。 递归调用方法次数过多

栈中存储方法运行时需要的数据

栈的运行原理 第一个方法被加载 入栈 在方法中调用了其他方法, 另一个方法入栈 方法运行结束后出栈.

栈帧的结构:
局部变量表: 方法参数,定义的局部变量, 基本值类型直接存值, 引用类型存地址.

操作数栈

动态链接

方法返回地址

4、Java 堆

5、方法区

http://www.ppmy.cn/devtools/163204.html

相关文章

突破“第一崇拜“:五维心理重构之路

一、视频介绍 在这个崇尚"第一"的时代&#xff0c;我们如何找到自己的独特价值&#xff1f;本视频将带您踏上五维心理重构之旅&#xff0c;从诗意人生的角度探讨如何突破"圣人之下皆蝼蚁"的局限。我们将穿越人生的不同阶段&#xff0c;从青春的意气风发到…

《Keras 3 使用 PointNet 进行点云分段》:此文为AI自动翻译

使用 PointNet 进行点云分段 作者:Soumik Rakshit、Sayak Paul 创建日期:2020/10/23 最后修改日期:2020/10/24 描述:实现基于 PointNet 的模型,用于分割点云。 (i) 此示例使用 Keras 3 在 Colab 中查看 GitHub 源 介绍 “点云”是用于存储几何形状数据的一种重要数据…

DeepSeek、微信、硅基流动、纳米搜索、秘塔搜索……十种不同方法实现DeepSeek使用自由

为了让大家实现 DeepSeek 使用自由&#xff0c;今天分享 10 个畅用 DeepSeek 的平台。 一、官方满血版&#xff1a;DeepSeek官网与APP 首推&#xff0c;肯定是 DeepSeek 的官网和 APP&#xff0c;可以使用满血版 R1 和 V3 模型&#xff0c;以及联网功能。 网址&#xff1a; htt…

是德科技keysight N5173B信号发生器,是一款经济高效的仪器

是德科技keysight N5173B信号发生器安捷伦N5173B信号源 是德N5173B微波模拟信号发生器&#xff0c;拥有 9 kHz 至 40 GHz 的频率覆盖范围&#xff0c;N5173B为宽带滤波器、放大器、接收机等器件的参数测试提供了必要的信号&#xff0c;是一款经济高效的仪器。 N5173B特点&…

低代码与开发框架的一些整合[3]

1.基本说明 审批流程是企业内部运营的运行流程&#xff0c;与业务板块进行关联&#xff0c;在企业数智化过程中启动业务串联的作用&#xff0c;与AI业务模型及业务agent整合后&#xff0c;将大大提升企业的运行效率以及降低运营风险。 近期对开源的近40个携带流程平台的项目进…

Skyeye 云智能制造办公系统 VUE 版本 v3.15.10 发布

Skyeye 云智能制造&#xff0c;采用 Springboot winUI 的低代码平台、移动端采用 UNI-APP。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公告、问卷、报表…

[LeetCode]day29 232.用栈实现队列

题目链接 题目描述 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 i…

C# 根据Ollama+DeepSeekR1开发本地AI辅助办公助手

在上一篇《访问DeepSeekR1本地部署API服务搭建自己的AI办公助手》中&#xff0c;我们通过通过Ollama提供的本地API接口用Python实现了一个简易的AI办公助手&#xff0c;但是需要运行Py脚本&#xff0c;还比较麻烦&#xff0c;下面我们用C#依据Ollama提供的API接口开发一个本地A…