JVM 运行原理


想要了解JVM的工作原理,首先得清楚JVM的概念以及体系结构。

JVM:java虚拟机,虚构的计算机,用来运行java代码。

JVM的体系结构:四大块,类装载子系统(class loader subsystem),执行引擎子系统(Executionengine子系统),垃圾回收系统(gc),运行时数据区(JVM内存)。

类加载器子系统:装载class文件的内容到运行时数据区中的方法区。加载过程是:当一个classloader启动时,它会去主机硬盘上去装载.class文件到运行时数据区的方法区,方法区中的这个字节文件会被虚拟机拿来在堆内存生成了一个字节码的对象。加载过程默认采用双亲委派机制。双亲委派机制,即某个加载器在收到加载请求时,首先将加载任务委托给自己的父类加载器,依次递归,如果父类加载器成功完成加载任务,则加载成功,否则自己加载。


执行引擎:类加载器子系统把代码逻辑都以指令的形式加载到了方法区,执行引擎负责执行这些指令。

圾回收系统?GC垃圾回收机制不是创建的变量为空是就被立刻回收,而是超出变量的作用域后就被自动回收。虚拟机的垃圾回收是一个典型的守护线程。

运行时数据区:五块,方法区(Method Area),java堆(Java Heap),本地方法栈(Native Method Stack),jvm栈(Java Virtual Machine Stack),程序计数器(Program Counter Register)。

方法区:虚拟机启动时创建,线程共享,用于存放已被虚拟机加载的类信息、常量、静态变量、以及编译后的方法实现的二进制形式的机器指令集等数据。

Java 堆:虚拟机启动时创建,线程共享,jvm内存最大的一块,gc的主要光顾对象。用于存放对象实例,几乎所有的对象实例以及数组都要在这里分配内存。


本地方法栈:线程私有,生命周期同线程,和jvm栈功能类似,区别:jvm栈执行java方法,本地方法栈执行native方法。native方法不是用java写的方法,它存在的意义是实现java代码不方便实现的缺陷。

Java虚拟机栈:线程私有,生命周期同线程,用来执行java方法。其中有个栈帧的概念,栈帧:存放当前线程中的局部基本类型的变量,部分返回结果,以及非基本类型指向堆中的地址。java虚拟机栈中最小单位可以理解为一个栈帧,一个方法对应一个栈帧。方法被调用产生栈帧压入栈,入栈出栈遵循先入后出原则。

程序计数器:线程私有,生命周期同线程,它可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令、分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。虚拟机执行native方法,pc寄存器中的值为undefined,因为native方法用不到解释器翻译,直接运行。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

JVM执行流程?
首先,当一个程序启动之前,它的class文件会被类装载器装入方法区,执行引擎读取方法区的字节码自适应解析,边解析就边运行(还有一种即时编译),然后pc寄存器指向了方法区中main函数所在位置,虚拟机开始为main函数在java栈(jvm栈)中预留一个栈帧(每个方法都对应一个栈帧,一次java方法的调用对应的是栈帧的入栈出栈操作),然后开始跑main函数,main函数里的代码被执行引擎映射成本地操作系统里相应的实现,然后调用本地方法接口,本地方法运行的时候,操纵系统会为本地方法分配本地方法栈,用来储存一些临时变量,然后运行本地方法,调用操作系统API等。

这就是JVM大体执行流程,描述的比较浅,深挖还有很多东西,比如执行引擎将方法区中的指令转成操作系统语言的两种方式:解释器,即时编译器,本地方法详解,堆的分区等等。



作者:makefire,发布于:2019/08/14
原文:https://www.cnblogs.com/makefire/p/11353044.html