快速理解 JVM 原理 - 【基础概念篇】

news2024/9/20 18:45:54

快速理解 JVM 原理 - 【基础概念篇】

Java虚拟机 是什么?

Java 虚拟机 本质就是一台”虚拟的“计算机 ,大家通俗的理解是一款 “软件”安装在电脑上

虚拟机通常分为两类:

  • 系统虚拟机【可运行完整操 作系统的软件平台】
  • 程序虚拟机 【为执行单个计算机程 序而设计】

无论是 哪种类型都被限制于虚拟机提供的资源中在这里插入图片描述

常见的编程语言类型

虚拟机和语言存在着 密不可分的关系,因此 Java 虚拟机也是基于 **虚拟机类似的静态编译性语言**。

常见的编程语言有三类

  1. 机器语言
    解释:直接向宿主机执行二进制指令0101,无需经过翻译,每一操作码在计算机内部都有相应的电路来完成它。
  2. 汇编语言
    任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言。可以使用助记符序列而不是数字操作代码,最计算机进行操作。
  3. 高级语言
    方便大家理解,进而快速设计和实现程序代码,代码完成后通过编译或解释 转换成汇编或者机器对应执行码在去机器中执行。
    在这里插入图片描述

Java 跨平台性体现

C语言 不同系统编译的文件形态是不同的
在这里插入图片描述
Java 语言 通过虚拟机统一处理编译成字节数据
在这里插入图片描述


    Java虚拟机组成

    Java虚拟机组成 主要由4部分组成

    • ClassLoader(类加载器)
    • Runtime Data Area(运行时数据区,内存分区)
    • Execution Engine(执行引擎)
    • Native Interface(本地库接口)

    核心流程

    在这里插入图片描述

    ClassLoader(类加载器)

    ClassLoader 负责加载字节码文件即 class 文件,class 文件在文件开头有特定的文件标示,并且 ClassLoader 只负责class 文件的加载。

    类的生命周期和加载过程

    一个类在JVM里的生命周期有7个阶段。
    分别是加载(Loading)、校验 (Verification)、准备(Preparation)、解析(Resolution)、初始化 (Initialization)、使用(Using)、卸载(Unloading)。 其中前五个部分(加载,验证,准备,解析,初始化)统称为类加载.
    在这里插入图片描述
    加载(Loading)

    就是 找到文件系统中/jar包中/或存在于任何地方的“ class文件 ”。 如果找不到二进制表示 形式,则会抛出 NoClassDefFound 错误
    装载阶段并不会检查 classfile 的语法和格式。

    校验(Loading)

    链接过程的第一个阶段是 校验 ,确保class文件里的字节流信息符合当前虚拟机的要 求,不会危害虚拟机的安全。

    准备(Preparation)

    进入准备阶段,这个阶段将会创建静态字段, 并将其初始化为标准默认值(比如 null 或者 0值 ),并分配方法表,即在方法区中分配这些变量所使用的内存空间。
    解析(Resolution)
    简单的来说就是我们编写的代码中,当一个变量引用某个对象的时候,这个引用在 .class 文件中是以符号引用来存储的(相当于做了一个索引记录)。 在解析阶段就需要将其解析并链接为直接引用(相当于指向实际对象)。如果有了直 接引用,那引用的目标必定在堆中存在。 加载一个class时, 需要加载所有的super类和super接口。
    初始化(Resolution)

    JVM规范明确规定, 必须在类的首次“主动使用”时才能执行类初始化。
    初始化的过程包括执行:

    • 类构造器方法 static
    • 静态变量赋值语句
    • static静态代码块
      如果是是一个子类进行初始化会先对其父类进行初始化,保证其父类在子类之前进行初 始化。所以其实在java中初始化一个类,那么必然先初始化过 java.lang.Object 类,因为所有的java类都继承自java.lang.Object。

    Execution Engine(执行引擎)

    执行引擎,也叫 Interpreter。Class 文件被加载后,会把指令和数据信息放入内存中,Execution Engine 则负责把这些命令解释给操作系统,即将 JVM 指令集翻译为操作系统指令集

    Native Interface(本地接口)

    负责调用本地接口的。核心作用是调用不同语言的接口给 JAVA 用,他会在 Native Method Stack 中记录对应的本地方法,然后调用该方法时就通过 Execution Engine 加载对应的本地 lib

    Runtime Data Area(运行时数据区,内存分区)

    在这里插入图片描述

    运行时描述摘抄参考文献 《深入理解JVM 虚拟机-第三版》 -周志明-尊重原创!!
    程序计数器
    程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的 字节码的行号指示器。在Java虚拟机的概念模型里[1],字节码解释器工作时就是通过改变这个计数器 的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处 理、线程恢复等基础功能都需要依赖这个计数器来完成。

    由于 Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的
    一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因 此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程 之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

    Java虚拟机栈
    与程序计数器一样,**Java虚拟机栈(Java Virtual Machine Stack)**也是线程私有的,它的生命周期 与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型: 每个方法被执行的时候,Java虚拟机都 会同步创建一个栈帧[1](Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
    由于 Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的。

    本地方法栈

    本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机 栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native) 方法服务。

    Java堆
    对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所 有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java 世界里“几乎”所有的对象实例都在这里分配内存。

    在这里插入图片描述

    方法区
    方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载 的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据

    **运行时常量池(Runtime Constant Pool)**是方法区的一部分。Class文件中除了有类的版本、字 段、方法、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),用于存放编译期生 成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。


      参考资料
      周志明-深入理解JVM数据

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

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

      相关文章

      AA-PEG-AA,Acetic Acid-PEG-Acetic Acid,羧酸-聚乙二醇-羧酸供应

      英文名称:Acetic Acid-PEG-Acetic Acid,AA-PEG-AA 中文名称:羧酸-聚乙二醇-羧酸 AA-PEG-AA是一种线性双功能PEG羧酸试剂。PEG和COOH基团之间存在亚甲基(CH2)键。AA-PEG-AA也称为CM-PEG-CM,CM:…

      【GD32F427开发板试用】使用TinyMaix进行手写数字识别

      本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:xusiwei1236 一、TinyMaix简介 TinyMaix是国内sipeed团队开发一个轻量级AI推理框架,官方介绍如下: TinyMaix 是面向单…

      django+mysql实现一个简单的web登录页面

      目录 一、使用pyacharm创建一个django项目 二、启动django项目验证 三、配置mysql数据库 1、本地安装mysql数据库 1)安装mysql数据库 2)自己创建一个数据库 2、安装 pymysql 3、配置mysql数据库 1)在项目同名包下的_init_.py里面添加…

      OpenGL渲染管线介绍

      一、概述 OpenGL是跨平台计算机图形应用程序的应用规范,广泛应用于仿真、游戏、GIS系统等领域,实现二三维图形的渲染。OpenGL渲染过程需要经历CPU、GPU两个阶段,CPU中进行图形计算,完成之后调用OpenGL开发接口在GPU中创建缓存区缓…

      前后端一些下载与配置(第二篇 第10天过后)nuxt banner redis

      NUXT 应该是不用怎么装? 有现成的 axios 还需要在npm吗 好像已经有现成的了 banner banner 笔记汇总P396 Redis Linux安装redis tar -xzvf redis-6.2.6.tar.gz cd redis-6.2.6 照着他做 然后 cd /usr/local/redis/bin ./redis-server /usr/local/redis…

      图数据建模基础

      Neo4j 图的组件 节点(Nodes)标签(Labels)关系(Relationships)属性(Properties)建模过程 了解领域并为应用程序定义特定用例(问题)。开发初始图形数据模型。 对…

      ansible的剧本(playbook)

      一、playbooks 概述以及实例操作 1、playbooks 的组成 playbooks 本身由以下各部分组成 (1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行 (2)Variables&#xff1…

      多模式支持无线监控技术:主动式定位、被动式定位

      物联网空间信息与数字技术发展至今,已经催生了一大批优秀的践行者。在日常与商业应用中,室内外定位领域依托于这一技术的发展,更是在近几年风光无限。但是并不是说室内定位与室外定位都已经相当成熟,相对来说,室内定位…

      简单实用的内网穿透实现教程

      内网穿透,字面理解就是网络地址穿透,是一种比较常用的将内网地址转换成公网地址的方式。通过内网穿透,可以将本地内网局域网提供给外网公网上访问,在外网也能连接访问内网主机和应用,当用户有日常远程和异地外网访问的…

      Zabbix的自定义监控

      Zabbix的自定义监控 zabbix自动可以提供很多监控项;但是往往不能满足需求;尝尝需要我们自己创建一系列的监控项,这就是自定义监控; 监控项:zabbix进行监控的一个指标,zabbix成为item; 它的值…

      C++7:STL-模拟实现vector

      目录 vector的成员变量 构造函数 reserve size() capacity() push_back 一些小BUG 赋值操作符重载 析构函数 【】操作符重载 resize pop_back Insert 迭代器失效 erase 二维数组问题 总结一下 vector,翻译软件会告诉你它的意思是向量,但其…

      面试腾讯测开岗,结束后被面试官吐槽“什么阿猫阿狗都敢来面试大厂了吗?”.....

      前一阵子有个小徒弟向我诉苦,说自己在参加某大厂测试面试的时候被面试官怼得哑口无言,场面让他一度十分尴尬 印象最深的就是下面几个问题: 根据你以前的工作经验和学习到的测试技术,说说你对质量保证的理解? 非关系型…

      不连接显示器或者HDMI欺骗器来 使用Moonlight串流游戏

      环境:WIN11NVIDIA显卡Moonlight串流 问题:当主机不连接显示器时,Moonlight客户端黑屏 解决办法:使用虚拟显示器来使显卡工资 背景:当SteamDeck 大卖的时候,我开始思考是否也需要购买一台Steam Deck来躺在床…

      G1垃圾回收器详解

      文章目录前言一、思考问题二、官方文档三、基本介绍四、G1的内存模型五、G1的标记过程六、G1的垃圾回收1、G1过程梳理2、Young GC3、Mixed GC4、Full GC七、参数介绍八、典型问题1、疏散失败(Evacuation Failure)2、大对象分配(Humongous All…

      【Linux】动静态库以及动静态链接

      环境:centos7.6,腾讯云服务器Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹链接扩展我们在使用Linux的时候,不禁会有这么一个疑问:为什么我们能够在Linux下进行c/c代码的编写以及编译呢?这是因…

      _Linux(网络基础)

      文章目录1. 相关基础概念2. 认识 "协议"3. 网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型4. 网络传输基本流程网络传输流程图数据包封装和分用小结5. 网络中的地址管理认识IP地址认识MAC地址认识端口号1. 相关基础概念 独立模式: 计算机之间相互独立网络互…

      MySQL数据库13——插入数据(INSERT)

      下面的语句用于向student表插入数据。 插入语句: INSERT INTO student(ID,name,sex,birthday,origin,contact1,contact2,institute) VALUES (0013,塔赛努,男,1997/9/15,内蒙古自治区,NULL,NULL,计算机学院);INSERT INTO student VALUES (0014,呼和嘎拉,男,1995-02…

      字节青训营——秒杀系统设计学习笔记(一)

      如何做系统设计 1. 场景分析(Scenario) 什么系统,需要哪些功能,多大的并发量 2. 存储设计(Storage) 数据如何组织,Sq|存储, NoSq|存储 3. 服务设计(Service) 业务功能实现和逻辑整合 4. 可扩展性(Scale) 解决设计缺陷&…

      Go的web开发Gin框架1(八)——Gin

      一、重点内容: 知识要点有哪些? 1、了解Gin框架 2、导入使用Gin框架 3、尝试配合GORM开发 4、整合html,css,js 二、详细知识点介绍: 1、Gin框架介绍 ​ Gin是一个golang的微框架,封装比较优雅&…

      MyBatis无法通过getGenerateKeys获得自增主键的问题

      我遇到这个问题的法伤原因比较蠢,查阅了网上相关经验都没有能够解决。看看这个经验能否帮助到你。问题描述:设置了属性的自增后想通过getGenerateKeys获得MySQL对应表单中自增主键id,检查了类、映射器、xml都没有发现问题,但是进行…