JVM详解(一)之初识JVM
前言:
一些有一定工作经验的开发人员,觉得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编译器输入的指令流基本上是一种基于栈的指令集架构,另一种指令集架构则是基于寄存器的指令集架构。
两者之间的区别如下:
- 基于栈式架构的特点:
- 设计和实现更简单,适用于资源受限的系统。
- 避开了寄存器的分配难题,使用零地址指令方式分配。(即指令没有地址,只有操作数)
- 指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈,指令集更小,编译器容易实现。
- 不需要硬件支持,可移植性更好,更好实现跨平台。
- 基于寄存器架构的特点:
- 典型的应用是x86的二进制指令集,比如传统的pc以及安卓的Davlik虚拟机。
- 指令集架构完全依赖于硬件,可移植性差。
- 性能优秀和执行更高效。
- 花费更少的指令去完成一项操作。
- 在大部分情况下,基于寄存器架构的指令集往往都以一地址指令(即指令有一个地址,一个操作数),二地址指令(指令有两个地址)和三地址指令为主。
下面我们比较一下进行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
- 点赞
- 收藏
- 关注作者
评论(0)