Java 笔记 JVM运行机制及基本原理

【深入理解JVM】:类加载机制 概述虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。与那些在编译时需要进行链接工作的语言不同,在Java语言里,类型的加载、连接和初始化过程都是在程序运行期间完成的,例如import java.util.*下面包含很多类,但是,在程序运行的时候,虚拟机只会加载哪些我们程序需要的类。这种策略虽然会 阅读详情

该博文是网上多篇博客的合集,算是自己的学习笔记摘抄。参考博客有:优快云_980979768、

Java的组成:

  • Java 由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(API)
  • 其中Java程序语言、Java虚拟机、JavaAPI类库这三个部分统称为JDK,JDK是用于支持Java程序开发的最小环境。
  • 把Java API类库中额Java SE API 子集和Java虚拟机这两部分统称为JRE,JRE是支持Java程序运行的标准环境。

JVM的位置:

  • JVM处在核心位置,是程序与底层操作系统和硬件无关的关键。

  • JVM是在Java编译器和os平台之间的虚拟处理器。是一种基于下层的操作系统和硬件平台并利用软件方法来实现的抽象计算机。 Java编译器只需要面向JVM,生成JVM能理解的字节码。

  • JVM 下方是移植接口,移植接口由两部分组成:适配器和Java操作系统。其中依赖于平台的部分称为适配器。

  • JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序 启动的时候,就产生JVM的一个实例。当程序运行结束时,实例也随之消失。

Java程序在JVM上运行的一般步骤:

1、Java源文件经编译器,编译成字节码(其中方法被编译为字节码指令)。

2、通过类加载器将字节码加载到虚拟机内存,并将字节码所代表的静态存储结构转化为方法区的运行时数据结构。

3、通过JVM解释器将每一条字节码指令翻译成特定平台上的机器码,然后通过特定平台运行。

Java虚拟机的体系结构:

每个JVM都有两种机制:

- 类装载子系统:装载具有适合名称的类或接口

  • 执行引擎:负责执行包含在已装载的类或接口中的指令

每个JVM包含内容

方法区、Java堆、Java栈、本地方法栈、指令计数器及其隐含寄存器

Java代码编译和执行的整个过程:

Java代码编译是由Java源码编译器来完成,也就是Java代码到JVM字节码(.class文件)的过程。 流程图如下所示:

Java字节码的执行是由JVM执行引擎来完成,流程图如下所示:

   此过程的三个重要机制:Java源码编译机制、类加载机制、类执行机制
Java源码编译机制:
  • 由以下三个过程组成:1)分析和输入到符号表 2)注释处理 3)语义分析和生成class文件

  • 最后生成的class文件由以下部分组成:
    1)结构信息包:括class文件格式版本号及各部分的数量与大小的信息;
    2)元数据:对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池;
    3)方法信息:对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息。

类加载机制:
  • 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

  • 与那些在编译时需要进行连接工作的语言不同,在Java语言里,类型的加载、连接和初始化过程都是在运行期间完成的,这种策略虽然会令类加载时稍微增加了一些性能开销,但是会为Java应用程序提供高度的灵活性,Java里天生可以动态扩展的语言特性就是依赖运行期动态加载和动态连接这个特点实现的。

初始化

什么情况下需要开始类加载过程的第一个阶段:加载?Java虚拟机规范并没有强制约束,这点依赖虚拟机的具体实现。

但是对于初始化阶段,虚拟机规范则严格规定了如下几种情况必须立即进行”初始化”(而加载、验证、准备自然需要在此之前开始)

1、使用new关键字实例化对象的时候、读取或设置一个类的静态字段的时候(被final修饰,已在编译期把结果放入常量池的静态字段除外),以及调用一个类的静态方法的时候。

2、使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。

3、当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

4、当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

以上场景中的行为称为对一个类的主动引用。除此之外,所有引用类的方式都不会触发初始化,称为被动引用。

接口的加载过程和类加载过程稍微有些不同。

接口与类真正区别在于:当一个类在初始化时,要求其父类全部都已经初始化过了,但是一个接口在初始化时,并不要求其父接口全部都完成了初始化,只有在真正使用到父接口的时候(如引用接口中定义的常量)才会初始化。

  • JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

  1. Bootstrap ClassLoader负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

  2. Extension ClassLoader负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包

  3. App ClassLoader负责记载classpath中指定的jar包及目录中class

  4. Custom ClassLoader属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader

类执行机制:
  • JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

  • JVM执行class字节码,线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。栈的结构如下图所示:

JVM内存管理

  • JVM内存结构分为:方法区(method),栈内存(stack),堆内存(heap),本地方法栈(Java中的jni调用),结构图如下所示:

堆内存
  • 所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。

  • 操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。但由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。这时由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

  • 另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,它不是在堆,也不是在栈,而是直接在进程的地址空间中保留一块内存,虽然这种方法用起来最不方便,但是速度快,也是最灵活的。

  • 堆内存是向高地址扩展的数据结构,是不连续的内存区域。由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

栈内存
  • 在Windows下, 栈是向低地址扩展的数据结构,是一块连续的内存区域。

  • 栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是固定的(是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。

  • 因此,能从栈获得的空间较小。只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。 由系统自动分配,速度较快。但程序员是无法控制的。

堆内存与栈内存需要说明:

++基础数据++类型直接在栈空间分配,++方法的形式参数++,直接在栈空间分配,当方法调用完成后从栈空间回收。引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量 。++方法的引用参数++,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完成后从栈空间回收。局部变量new出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收。方法调用时传入的literal参数,先在栈空间分配,在方法调用完成后从栈空间收回。字符串常量、static在DATA区域分配,this在堆空间分配。数组既在栈空间分配数组名称,又在堆空间分配数组实际的大小。

  • 个人小结:new操作的是在堆开辟控件,而引用和一般的基础数据类型是在栈空间分配。
本地方法栈(Java中的jni调用)
  • 用于支持native方法的执行,存储了每个native方法调用的状态。对于本地方法接口,实现JVM并不要求一定要有它的支持,甚至可以完全没有。Sun公司实现Java本地接口(JNI)是出于可移植性的考虑,当然我们也可以设计出其它的本地接口来代替Sun公司的JNI。但是这些设计与实现是比较复杂的事情,需要确保垃圾回收器不会将那些正在被本地方法调用的对象释放掉。

  • 个人小结:看不懂 >_<

方法区
  • 它保存方法代码(编译后的java代码)和符号表。存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。JVM用持久代(Permanet Generation)来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。

Java虚拟机的运行过程示例

上面对虚拟机的各个部分进行了比较详细的说明,下面通过一个具体的例子来分析它的运行过程。

虚拟机通过调用某个指定类的方法main启动,传递给main一个字符串数组参数,使指定的类被装载,同时链接该类所使用的其它的类型,并且初始化它们。例如对于程序:

编译后在命令行模式下键入: java HelloApp run virtual machine

将通过调用HelloApp的方法main来启动java虚拟机,传递给main一个包含三个字符串”run”、”virtual”、”machine”的数组。现在我们略述虚拟机在执行HelloApp时可能采取的步骤。

开始试图执行类HelloApp的main方法,发现该类并没有被装载,也就是说虚拟机当前不包含该类的二进制代表,于是虚拟机使用ClassLoader试图寻找这样的二进制代表。如果这个进程失败,则抛出一个异常。类被装载后同时在main方法被调用之前,必须对类HelloApp与其它类型进行链接然后初始化。链接包含三个阶段:检验,准备和解析。检验检查被装载的主类的符号和语义,准备则创建类或接口的静态域以及把这些域初始化为标准的默认值,解析负责检查主类对其它类或接口的符号引用,在这一步它是可选的。类的初始化是对类中声明的静态初始化函数和静态域的初始化构造方法的执行。一个类在初始化之前它的父类必须被初始化。整个过程如下:

![](https://img-blog.youkuaiyun.com/20131106014016937?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveF9wYW5kYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
)

掌握一定知识后,进一步阅读:Java JVM 运行机制及基本原理


字节码

  • Java语言中,程序编译后生成的是字节码而不是机器码。字节码不包含任何平台相关的信息,故具有平台无关性。

  • Java虚拟机的语言无关性。Java虚拟机不和包括Java语言在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联,也就是说,虚拟机并不关心Class(描述类静态结构的字节码)的来源是何种语言。

【Java 入门】Java 初识、编译运行机制及开发环境搭建 Java 入门篇 —— Java 开发语言初识,编译运行原理介绍,Java 开发环境的搭建,附详细演示与软件下载地址。 阅读详情

相关推荐

GEE AI: 利用 Satellite Embedding 语义搜索快速识别研究区目标斑块

摘要 本文介绍了一种基于Google Earth Engine的遥感语义搜索技术,利用Satellite Embedding数据集快速识别目标地物。该方法通过将光谱信息转化为高维向量,在武汉市的案例中展示了如何:1)定义研究区和样本点;2)加载预处理的Embedding数据;3)计算向量相似度;4)结合面积过滤优化结果。相比传统监督分类,该技术具有响应快速(无需模型训练)、抗季节干扰和精准界定等优势,特别适用于森林碳储量监测和土地利用检测等应用场景。文中提供了完整的GEE代码实现流程,包括样本定义、相似度计

此星光明博客 622

膜拜大佬!JVM性能调优——JVM内存模型和类加载运行机制

一、JVM内存模型 运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包。因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分。JVM 不仅承担了 Java 字节码的分析和执行,同时也内置了自动内存分配管理机制。这个机制可以大大降低手动分配回收机制可能带来的内存泄露和内存溢出风险,使 Java 开发人员不需要关注每个对象的内存分配以及回收,从而更专注于业务本身。 在 Java 中,JVM 内存模型主要分为堆、方法区、程序计数...

小梦爱Java的博客 883

振动信号相位测量的关键技术解析

本文深入解析了振动信号相位测量的关键技术,强调相位是振动信号的“身份证”,对于动平衡和故障诊断至关重要。文章详细阐述了键相传感器与振动传感器的选型、安装要点,以及时域和频域(FFT)核心算法,并针对现场噪声、转速波动等挑战提供了实战解决方案,帮助工程师实现精准、稳定的相位测量。

vv45678的博客 838

Java Jvm运行机制原理

一:简介在学习Java虚拟机之前,也就是Jvm之前,我想大家能够带着问题去学习,这样的话,大家学习起来也会比较有所获! 1.Java虚拟机(Jvm)是什么? 2.Java虚拟机是用来干什么的? 3.Java虚拟机它的体系结构是什么样子的? 4.Java虚拟机在工作做扮演什么角色? 5.Java虚拟机在运行时数据区?二:Jvm基础概念Java虚拟机(Jvm)是可运行Java代码的假想计算机Ja

ZengTao 4万+

手把手教你调试RTL8201F:从芯片手册解读到LWIP驱动移植

本文详细解析了RTL8201F PHY芯片的开发流程,从寄存器配置到LWIP驱动移植,重点介绍了RMII模式下的特殊配置要点和调试技巧。通过实战案例和高级调试方法,帮助工程师解决网络性能问题,实现与FreeRTOS+LWIP协议栈的稳定集成。

ik678901234的博客 972

MaxKey+JeecgBoot单点登录实战:手把手教你从零配置到账户同步

本文提供MaxKey与JeecgBoot单点登录(SSO)的实战整合指南。详细讲解从MaxKey应用注册、JeecgBoot前后端改造,到最终实现账户同步的完整步骤,重点解决Shiro配置、令牌交换等关键问题,帮助企业构建统一、可扩展的身份管理体系。

weixin_29258297的博客 540

【鲁班学院】面试总结:Java高级篇(下),抽象类和接口的关系以及对内存和栈内存的区别等...

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34409703的博客 218

vcpkg管理OpenCASCADE的5个高效技巧:从多版本共存到离线部署

本文详细介绍了使用vcpkg高效管理OpenCASCADE的5个实用技巧,包括多版本共存、性能优化、团队共享、CI/CD集成和离线部署。通过自动配置和版本控制,vcpkg显著简化了OpenCASCADE的开发环境管理,特别适合工业级CAD开发场景。

rain6的博客 187

Java学习笔记(二)JVM运行原理

本篇博客对Java编译、JVM结构与流程、JVM运行时数据区、类的装载、JVM执行子系统、对象的创建以及JVM的GC子系统作了简要介绍与总结。

xmj_csdn的博客 530

基于STM32L4XX、HAL库的BQ25713RSNR充电芯片驱动程序设计

define BQ25713_I2C_ADDR (0x6B << 1) // 7位地址为 0x6B,HAL库需要左移一位。// 示例:配置 CHARGE_OPTION_0 寄存器:使能充电,使能 ICO(输入电流优化)reg_data |= (EN_CHG_MASK | EN_ICO_MASK);

zhusl6688的博客 406

学Simulink--基于Simulink的无迹卡尔曼滤波(UKF)目标跟踪仿真建模示例

本文详细介绍了基于Simulink的无迹卡尔曼滤波(UKF)目标跟踪仿真建模方法。首先分析了UKF相比EKF在强非线性场景下的优势,包括无线性化误差、计算效率高和鲁棒性强等特点。接着阐述了UKF的核心原理,重点讲解了无迹变换(UT)的三个关键步骤:Sigma点生成、非线性传播和加权统计重构。文章还详细说明了二维机动目标的状态向量定义、非线性状态转移模型和雷达观测模型。 在Simulink实现部分,提供了完整的建模步骤和核心代码,包括目标运动模型、雷达传感器模型和UKF算法模块的实现。通过蛇形机动场景的仿真实

xiaoheshang_123的博客 89

Java JVM 运行机制及基本原理

Java JVM 运行机制及基本原理 将知识用文字记录下来,供以后温故知新。 JVM的基础概念 JVM的中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机。 JVM也充当着一个翻译官的角色,我们编写出的Java程序,是不能够被操作系统所直接识别的,这时候JVM的作用就体现出来了,它负责把我们的程序翻译给系统“听”,告诉它我们的程序需要做什么操作。 我们都知道...

尚拙的博客 199

如何从 VMware 官网下载最新版本的 VMware Workstation

如何从 VMware 官网下载 VMware Workstation

XiaoqiangClub的博客 5874

JVM运行机制

JVM运行机制 先了解jdk,jre,jvm 1.什么是JDK? JDK 是 java development kit(java 开发工具包)的缩写。每个学 java的人都会先在机器上装一个JDK,那让我们看一下 JDK 的安装目录。在目录下面有六个文件夹、一个 src 类库源码压缩包、和其他几个声明文件。其中,真正在运行 java 时起作用的是以下四个文件夹:bin、include、lib、jre。JDK,JRE,JVM 三者关系概括如下: 现在我们可以看出这样一个关系,JDK 包含 JRE,而 JRE

MT 1628

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java运行机制

Java应用程序的开发周期包括编译、下载、解释和执行几个部分。Java编译程序将 Java源程序翻译为JVM可执行代码--字节码。再由解释器在运行过程中创立内存布局,然后再通过查表来确定一个方法所在的地址。这样就有效的保证了Java的可移植性和安全性。

个人学习笔记库,一篇一篇记录成长的足迹 1万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java运行机制与JVM、JRE、JDK--是什么

什么是 JDK? JDK 是 Java Development Kit的缩写 什么是 JRE? 什么是 JVM?

lyh1023812的博客 1414

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【JVM】——JVM运行机制、类加载机制、内存划分

JVM运行机制,堆栈,程序计数器,元数据区,JVM加载机制,双亲委派模型

阿华的博客 1299

JAVA JVM 运行机制和基本原理

JVM的基础概念 JVM的中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机。 JVM也充当着一个翻译官的角色,我们编写出的Java程序,是不能够被操作系统所直接识别的,这时候JVM的作用就体现出来了,它负责把我们的程序翻译给系统“听”,告诉它我们的程序需要做什么操作。 我们都知道Java的程序需要经过编译后,产生.Class文件,JVM才能识别并运行它,JVM针对每个操作系统开发其对应的解释器,所以只要其操作系统有对应版本的JVM,那么这份Java编译后的代码就能够运行起来,这就是

gym02的博客 851

Java JVM运行机制及基本原理

(Java Virtual Machine,JVM)是Java平台的,它是在计算机上运行Java字节码文件(.class)的虚拟机,在任何平台上都提供给编译程序一个公共的接口,使字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行,且JVM非常小,每个平台都容易实现,可以说java程序编译成的字节码文件做到了“一次编译,随处运行”造就了Java开发的特性,使得Java程序可以在不同的操作系统和硬件上运行。

m0_59704905的博客 779

【Java】Java JVM运行机制及基本原理

一. JVM基础概念 JVM的中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机。 JVM也充当着一个翻译官的角色,我们编写出的Java程序,是不能够被操作系统所直接识别的,这时候JVM的作用就体现出来了,它负责把我们的程序翻译给系统“听”,告诉它我们的程序需要做什么操作。 我们都知道Java的程序需要经过编译后,产生.class文件,JVM才能识别并运行它,JVM针对每个...

藏经阁 | 玄苦 610

jvm运行机制

jvm运行机制 jvm的基本结构 PC寄存器 每个线程拥有一个PC寄存器 在线程创建时会创建 PC寄存器会指向下一条指令的地址 线程共享的: 方法区:类的共有属性,保存相对稳定信息。 JVM堆:对象、数组,是GC的主要工作区间 线程隔离的:(双栈是隔离的) 本地方法栈:Natitve 方法 虚拟机栈(JVM方法栈、JAVA栈):局部变量区和操作数栈、存放基本类型的数据和对象的引用 内存模型 ...

蹊源的奇思妙想的博客 2315

【JVM】JVM运行机制

类是如何被加载到jvm并且在jvm中执行的? 从这个问题出发,首先我们需要知道jvm的内存结构包括什么。 下图为JVM的结构图,主要包括垃圾回收器,类加载子系统,执行引擎,运行时数据区等。 类加载子系统:把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化最终形成可以被JVM直接使用的Java类型。 运行时数据区 程序计数器: 在JVM的概念模型里,字节码解释器工作时就是...

努力发光呀 471
上一篇: Java 笔记【第三章 Java 的基本程序设计结构】
下一篇: Java 笔记【第四章 对象与类】
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值