JVM基础概念

不同的操作系统上运行的JVM是不一样的,都专门为不同到的操作系统开发了一个jvm。

java是编译+解释合一的,如果直接用jvm解释java文件,就是解释型语言,速度会变慢,先编译好,等运行的时候就只要解释就行,速度会快很多。

JVM是建立在操作系统上的,Java虚拟机屏蔽了开发人员与操作系统的直接接触,我们在通过Java编写程序时,只需要负责编写Java代码即可,关于具体的执行则会由JVM加载字节码后翻译成机械指令交给OS执行。

在Java之前,无论是C语言还是汇编等这类的底层语言开发出的程序,在不同的环境/系统下都需要进行重新编译代码后才能执行的。而Java则反其道而行之,不再需要根据不同的环境而改变自己的代码,而是自己架构出了一个平台,开发人员编写出的代码只需要能够在自己平台上执行即可,完全屏蔽了开发者与操作系统的接触,而这个Java自身架构出的平台则被称为JVM。

JVM具有跨语言性,任何一门语言只要能够转换成JVM能识别读取的class文件,都能够被JVM接受并执行。

JDK、JRE、JVM:

虚拟机的两种架构:

虚拟机主要有两种架构模型,一种是基于栈式的,另一种则是基于寄存器式的。从性能上说,基于寄存器模型会比基于栈式的虚拟机性能更好,但是从移植性上看,栈式的虚拟机会远强于基于寄存器模型的虚拟机。

基于栈式的虚拟机(JVM):

基于栈式指的是虚拟机在执行指令时,采用的方式是基于栈的指令集,会将需要执行的指令一条条的压入栈中,主要有入栈和出栈两种操作,计算结果最终存储在栈中。基于栈式的虚拟机都会存在一个操作数栈的概念,虚拟机在真正运算时,都是通过操作数栈进行操作,与内存进行交互,简单来说就是无论任何操作,都需要通过操作数栈进行。这种模型的虚拟机最大的好处在于可以无视硬件、物理架构。当然,缺点也非常明显,因为无论什么操作都要经过操作数栈,所以性能会低一些。

Java的JVM、Python的CPython、.Net的CLR等虚拟机都是基于这种栈式模型的。

从如上步骤可以看出,一次简单的加法运算就需要经过七次总线传输,因为所有操作都要经过操作数栈的原因,所以效率方面会低许多。

基于寄存器的虚拟机:

基于寄存器模型的虚拟机存在很多虚拟寄存器的概念,用于模拟CPU中真实PC寄存器,但它们往往都以别名存在,如R1、R2、R3等,在执行时,执行引擎需要对这些别名进行解析,然后找出具体操作数的位置,然后取出操作数进行操作。这些虚拟的寄存器也并不是直接在CPU中的,而是和操作数栈一样,位于运行时栈中,通过一个数组(运行时栈帧中的连续内存空间)存储所有的虚拟寄存器。

其实"寄存器"的概念只是当前栈帧中一块连续的内存区域。这些数据在运算的时候,直接送入物理CPU进行计算,无需再传送到operand stack上然后再进行运算。例如"ADD R3, R2, R1"的示意图就如下所示:

JVM的生命周期:

JVM在Java程序开始执行的时候,它才运行,程序结束的时它就停止。

一个Java程序会开启一个JVM进程,如果一台机器上运行三个程序,那么就会有三个运行中的JVM进程。

JVM中的线程分为两种:守护线程和普通线程

守护线程是JVM自己使用的线程,比如垃圾回收(GC)就是一个守护线程。

普通线程一般是Java程序的线程,只要JVM中有普通线程在执行,那么JVM就不会停止。

现在占绝对地位的虚拟机为HotSpot。

运行时数据区是在内存中的,是专门分给JVM的一块内存区域。

一个 JVM 实例对应一个进程。JVM 的运行时数据区由这个 JVM 实例管理。内存中可以有多块运行时数据区。

如果在一台机器上运行多个 JVM 实例,每个 JVM 都会独立分配运行时数据区。

这里面的程序计数器和cpu的寄存器中的程序计数器不是同一个。jvm中的程序计数器线程私有,记录的是当前的线程的字节码指令地址是一个逻辑概念;而寄存器中的程序计数器是硬件寄存器,记录的是cpu的机器指令地址。

本地方法栈:调用native方法,不会创建栈帧,而是通过动态链接并直接调用该方法;

方法区:存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码数据。

在jdk1.8中不存在方法区,原方法区被分成两部分;1:加载的类信息,2:运行时常量池;类信息保存在元数据区,运行时常量池保存在堆。

栈占空间小,由操作系统管理

堆占空间大,由jvm管理

Java虚拟机一般是由多个模块一起组成的,主要可分为类加载子系统、执行引擎子系统、运行时数据区、垃圾回收子系统以及本地接口和本地方法库。

什么是JVM内存模型?

定义了Java程序在运行时如何管理内存,包括内存的划分、访问、线程间的可见性( 多线程环境中如何保证共享变量可见性,通过内存屏障、volatile关键字和同步机制 )和一致性等

相关推荐
01二进制代码漫游日记5 小时前
C/C++中的内存区域划分
c语言·jvm·数据结构·学习
三无少女指南5 小时前
聊聊JVM里的符号引用、直接引用与动态分派
jvm
一叶飘零_sweeeet6 小时前
JVM 运行时数据区全解:从底层原理到 OOM 根因定位全链路实战
jvm
傻啦嘿哟8 小时前
爬虫跑了一小时还没完?换成列表推导式,我提前下班了
java·开发语言·jvm
摇滚侠8 小时前
java: Cannot compile module ‘consumer‘ configured for JVM target 17
java·jvm
木易 士心9 小时前
Java中 synchronized 和 volatile 详解
java·开发语言·jvm
JustMove0n11 小时前
互联网大厂Java面试全流程问答及技术详解
java·jvm·redis·mybatis·dubbo·springboot·多线程
Nuopiane21 小时前
关于C#/Unity中单例的探讨
java·jvm·c#
win x21 小时前
JVM类加载及双亲委派模型
java·jvm