JVM详解(一)之初识JVM

举报
YuShiwen 发表于 2022/03/31 00:38:42 2022/03/31
【摘要】 前言: 一些有一定工作经验的开发人员,觉得SSM、微服务等上层技术才是重点,而忽略了基础的技术,这其实是不可取的,作为一个想向上发展的开发人员,打好基础是最关键的,不然基础的知识永远是你的致命缺点! 关于...

前言:
一些有一定工作经验的开发人员,觉得SSM、微服务等上层技术才是重点,而忽略了基础的技术,这其实是不可取的,作为一个想向上发展的开发人员,打好基础是最关键的,不然基础的知识永远是你的致命缺点!
关于JVM详解的博文将以连载方式持续发布到个人分类专栏的JVM详解中,欢迎大家关注,点赞,评论。如果有一些问题暂时不太清楚的可以拿小本本记下,在之后的博文中会详细说明。

一.虚拟机

所谓虚拟机(Virtual Machine),就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。

  • 大名鼎鼎的Visual Box ,VMware就属于系统虚拟机,它们完全是对物理计算机的仿真,提供了一个可运行完整操作系统的软件平台。
  • 程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。

无论是系统虚拟机还是程序虚拟机,在上面运行的软件都被限制于虚拟机提供的资源中。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行

二.JVM所在部分的简化图:

在这里插入图片描述

三.Write once , run anywhere图解:

在这里插入图片描述

四.初识Java虚拟机

  • Java虚拟机是Java平台的基石。它是该技术的组成部分,负责硬件和操作系统的独立性,已编译代码的小尺寸以及保护用户免受恶意程序攻击的能力。(所谓已编译代码的小尺寸,举例例子来说比如说在一个程序当中用到了String,用到了基本数据类型,用到其它一些类啊等等,其实我们在真正编译以后的字节码文件都对应着一个常量池,运行的时候我们叫运行时常量池,我们通过这些常量的指向,来避免我们在字节码文件中去加载大量的类,保证了字节码文件的小尺寸。)
  • Java虚拟机是抽象的计算机。像真正的计算机一样,它具有指令集并在运行时操作各种内存区域。
  • Java虚拟机对Java编程语言一无所知,仅识别特定的二进制格式(class文件格式)。一个class文件包含Java虚拟机指令和符号表,以及其它辅助信息。
  • 为了安全起见,Java虚拟机对class文件中的代码施加了严格的语法和结构约束。但是,任何具有可以用有效字节码文件表示的功能语言都可以由Java虚拟机承载。被一个普遍可用的、独立于机器的平台所吸引,其他语言的实现者可以将Java虚拟机作为其语言的传递工具。(即JVM是跨语言的平台,只需要不同的编程语言提供各自的编译器,他们各自带编译器编译出来的字节码文件遵循java虚拟机的规范,我们的java虚拟机就可以解释运行 ,图解如下):
    在这里插入图片描述

五.基于栈的指令集架构和基于寄存器的指令集架构

Java编译器输入的指令流基本上是一种基于栈的指令集架构,另一种指令集架构则是基于寄存器的指令集架构
两者之间的区别如下:

  • 基于栈式架构的特点:
  1. 设计和实现更简单,适用于资源受限的系统。
  2. 避开了寄存器的分配难题,使用零地址指令方式分配。(即指令没有地址,只有操作数)
  3. 指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈,指令集更小,编译器容易实现。
  4. 不需要硬件支持,可移植性更好,更好实现跨平台。
  • 基于寄存器架构的特点:
  1. 典型的应用是x86的二进制指令集,比如传统的pc以及安卓的Davlik虚拟机。
  2. 指令集架构完全依赖于硬件,可移植性差。
  3. 性能优秀和执行更高效。
  4. 花费更少的指令去完成一项操作。
  5. 在大部分情况下,基于寄存器架构的指令集往往都以一地址指令(即指令有一个地址,一个操作数),二地址指令(指令有两个地址)和三地址指令为主。

下面我们比较一下进行3+5操作时,基于栈的指令集架构与基于寄存器的指令集架构的指令的区别:
程序:
在这里插入图片描述

编译后的字节码文件路径:
在这里插入图片描述
在idea终端cd进入Test01.class文件所在路径,输入javap -v Test01.class 进行反编译:
在这里插入图片描述

我们可以看到Code那块,就是我们的指令了,对其指令简单解释:

指令 作用
iconst_3 定义常量3
istore_1 保存到索引为1的位置
iconst_5 定义常量5
istore_2 保存到索引为2的位置
iload_1 把索引为1的加载进来
iload_2 把索引为2的加载进来
iadd 对刚才加载进来的值做求和操作
iconst_3 求和操作所得值存入到索引为3的位置

以上是基于栈的指令集架构的指令,看着指令的数量是比较多的,而对于基于寄存器的指令集架构,其指令如下:

指令 作用
move AX,3 将AX寄存器的值设为3
add AX,5 把AX寄存器中的值与5相加结果保存到AX寄存器中

可以看出执行同样的操作,基于寄存器的指令集架构的指令数量比较少,但其指令集架构完全依赖于硬件,可移植性差。

总结:
由于JVM跨平台的设计,不同平台cpu的架构不同,所以Java的指令不能设计为基于寄存器的,而是基于栈的指令集架构;
它的优点是跨平台,指令集小,编译容易实现,缺点是性能下降,实现同样的功能需求需要更多的指令。

六.JVM的整体结构

在这里插入图片描述

七.JVM的生命周期

1.虚拟机的启动

Java虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实现指定的。

2.虚拟机的执行

  • 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序。
  • 程序开始执行时它才运行,程序结束时它就停止。
  • 执行一个所谓的Java程序的时候,真正在执行的是一个叫做Java虚拟机的进程。

3.虚拟机的退出

虚拟机的退出有如下几种情况:

  • 程序正常执行结束
  • 程序在执行过程中遇到了异常或错误
  • 由于操作系统出现错误而导致Java虚拟机进程终止
  • 某线程调用Runtime类或System类的exit方法,或Runtime类的halt方法,并且Java安全管理器也允许这次的exit或halt操作。
  • 除此之外,JNI(Java Native Interface) 规范描述了用JNI Invovation API 来加载或卸载Java虚拟机时,Java虚拟机的退出情况。

未完待续,博文持续跟新中…

文章来源: blog.csdn.net,作者:Mr.Yushiwen,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/MrYushiwen/article/details/107899966

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。