JVM运行原理

对于JVM运行原理一知半解,网上也说的五花八门,不够系统。本文先从百科着手,初识JVM

JVM的概念:

JVM是Java Virtual Machine(Java虚拟机)的缩写,是一个抽象的计算模型,就如同一台真实的机器,它有自己的指令集和执行引擎,可以在运行时操控内存区域,其目的是为构建在其上运行的应用程序提供一个运行环境。

既然JVM 是java虚拟机的缩写,那我就想知道JVM与java有什么关系了。

JVM 和 JAVA 的关系: 

首先java是一种计算机编程语言,它有自己的一套技术体系,这我们都很熟悉:

 技术体系:

    1. java编程语言

    2.Java类文件格式 (字节码文件)

    3.Java API,包括Java API类库和来自商业机构以及开源社区的第三方类库

    4.虚拟机

 

《JVM运行原理》

 

当编辑并运行一个Java程序时,需要同时涉及到这四种方面。使用文字编辑软件(例如记事本写字板UltraEdit等)或集成开发环境Eclipse、MyEclipse等)在Java源文件中定义不同的类,通过调用类(这些类实现了Java API)中的方法来访问资源系统,把源文件编译生成一种二进制中间码,存储在class文件中,然后再通过运行与操作系统平台环境相对应的Java虚拟机来运行class文件,执行编译产生的字节码,调用class文件中实现的方法来满足程序的Java API调用简而言之:java编程语言规范 编写java程序,根据javaAPI把源文件进行编译成二进制中间码,存储在java类文件中,最后通过jvm类运行此文件。

java的优点在这里不做具体细说,大家也都知道哈。

要说的是java的跨平台性,使它摆脱了硬件平台的束缚,实现了“一次编写、到处运行”,使跨越不同平台编写程序成为了可能,这完全归功于Java虚拟机。Java虚拟机负责Java程序设计语言的安全特性和平台无关性,屏蔽了与具体操作系统平台相关的信息,使得Java语言编译器只需要生成在Java虚拟机上运行的字节码,就可以在多种平台上不加修改地运行。要多提一句,我们现在说的Java虚拟机基本上都是JDK自带的虚拟机HotSpot,这款虚拟机也是目前商用虚拟中市场份额最大的一款虚拟机。

 JVM的运行原理:

在了解JVM运行原理之前,先要大致熟悉JVM的逻辑内存模型:

《JVM运行原理》

 1. 程序计数器

程序计数器是用于存放下一条指令所在单元的地址的很小的一块内存空间。

    计算机中的处理器要执行的程序(指令序列)都是以二进制代码序列方式预存储在计算机的存储器中,处理器将这些代码逐条地取到处理器中再译码、执行,以完成整个程序的执行。为了保证程序能够连续地执行下去,CPU必须具有某些手段来确定下一条取指指令的地址。程序计数器(PC )正是起到种作用,所以通常又称之为‘指令计数器’。首先需要根据程序计数器(PC )中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。与此同时,程序计数器(PC )中的地址或自动加1或由转移指针给出下一条指令的地址。此后经过分析指令,执行指令。完成第一条指令的行,而后根据程序计数器(PC )取出第二条指令的地址,如此循环,执行每一条指令。简而言之,就是存储处理器需要执行程序的指令序列的地方。保证程序执行的连续性。。

    Java虚拟机中的程序计数器是Java运行时数据区中的一小块内存区域,但是它的功能和通常的程序计数器是类似的。由于Java 虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。如果线程正在执行的是一个Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie 方法,(主要用于加载文件和动态链接库)这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java 虚拟机规范中没有规定任何OutOfMemoryError 情况的区域。

2.Java 栈

Java栈描述的是Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame )用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。我们开发过程过程中所关注的栈,即java栈就是局部变量表部分的内存。局部变量表存放了编译期可知的各种基本数据类型,原始类型(primitive类型,基本数据类型)、引用类型(reference 类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress 类型(指向了一条字节码指令的地址)。其中64 位长度的long 和double 类型的数据会占用2 个局部变量空间(Slot),其余的数据类型只占用1 个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。在Java 虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常;如果虚拟机栈可以动态扩展当前大部分的Java 虚拟机都可动态扩展,只不过Java 虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError 异常。

3.本地方法栈

保存native方法进入区域的地址。

虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如Sun HotSpot 虚拟机)直接就把本地方法栈和虚拟机栈合二为一。

4.java 堆

Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块。Java 堆是被所有线程共享的一块内存区域,也是供所有类实例和数组对象分配内存的区域,在虚拟机启动时创建。同时 Java 堆也是垃圾收集器管理的主要的区域,因此也叫 GC 堆(Garbage Collected Heap ),由于垃圾收集器可以采用不同的方式,对 Java 堆还进行了进一步的划分。可分为新生代/老年代,或者划分为 Eden 空间/From Survivor空间/To Survivor 空间。

 

《JVM运行原理》

java虚拟机规范中描述:Java 堆的容量可以是固定的,也可以是随着程序 执行的需求动态扩展,并在不需要过多空间是自动收缩,Java堆中所使用的内存不需要保证连续型。并且java虚拟机实现应当给与程序员或者最终用户调节java堆的初始容量的手段,对于可以动态 扩展和收缩java堆来说,则应当提供调节其最大的,最小容量的手段,如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常。

5.方法区  —- Non-Heap(非堆)

方法区,和java堆一样被所有线程共享的一块区域。是堆的逻辑组成部分,但是和堆还是有区别的,故别名为 Non-Heap (非堆)。同样在虚拟机启动时创建,内存空间具有伸缩型,可扩展。当方法区无法满足内存分配需求时,将抛出OutOfMemoryError 异常。

它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。说的具体一点,它存储了每一个类的具体结构信息,运行时常量池,字段,方法数据,构造函数和普通方法的字节码内容,还包括一些在类,实例,接口初始化时用到的特殊方法。

6.运行时常量池

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

常量池这一块没有 搞清楚,后续补充。主要是 字符串常量池,class常量池和运行时常量池的定义和解释。

jvm运行原理:

JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种基于下层的操作系统和硬件平台并利用软件方法来实现的抽象的计算机,可以在上面执行java的字节码程序。

JVM执行程序的过程 :1.加载.class文件 2.管理并分配内存 3.执行垃圾收集
 
JVM在整个jdk中处于最底层,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也叫虚拟计算机.操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境。
 
1.创建JVM装载环境和配置  
2.装载JVM.dll  
3.初始化JVM.dll并挂接到JNIENV(JNI调用接口)实例  
4.调用JNIEnv实例装载并处理class类。     
                                                                                                                             《JVM运行原理》

 

     

    原文作者:最咸的那一条
    原文地址: https://www.cnblogs.com/bearhunting/p/9915154.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞