背景:学习了这么多年的Java,把自己的理解写成JVM系列,以便于后面的温习,以及帮助更多的java开发人员。
开篇先梳理下,我们之前写的第一个Hello World!,当我们运行出来后,在控制台打印的那种激动心情,但是他的背后是如何运行的呢?那么问题来了,我们写的java代码到底是如何运行起来的,中间又经历了什么?带着我这些问题,我们继续往下看。
首先假设我们写好了一个java代码,在IDEA或者Eclipse工具上,会有一个“.java“后缀的代码文件,我们写好后,想要部署到线上的机器上去运行,一般都是把代码通过IDEA工具编译生成".class"后缀文件后,再进行打包,打包成“.jar”后缀的jar包,或者 “.war” 后缀的war包; 最后再通过 tomcat部署 ,或者 java 命令进行运行;是不是这样的一个过程;粗略的看确实是这样一个过程,来看下图,来回忆下这个过程:
上面的过程中,java代码通过idea工具编译后,生成“.class” 后缀的,字节码文件(字节码是能够被虚拟机认识的16进制字节,其中还有一些字节码指令等等的内容),那么,我们编译好的文件是如何运行起来的呢?
这个时候我们就要使用一个“Java -jar”的命令,来运行程序,实际上此时就会启动一个JVM进程,这个JVM就会负责运行这些“.class” 字节码文件,相当于负责运行我们写好的系统。
对于上面的过程,IDEA编译打包代码的过程,我们暂时不在这块过多的说明,我们把重点放到运行这块上来,这块才是核心内容,下面就说下打包后,部署运行的内部是如何运行的?
当我们运行了一个"java -jar" 命令后,就是启动了一个JVM进程,就会运行我们编写的字节码文件对吧,我们按照逆推的方式来理解,既然要执行字节码,我们是不是要先找到字节码文件,那么怎么找呢,找到后怎么读取执行,针对这两个问题,我们引出了两个概念 “类加载器”,“字节码执行引擎”,类加载器很好理解,字面意思,就是把类加载到JVM中,以供后续代码运行使用;
字节码执行引擎,就是JVM会基于自己的字节码引擎来执行类加载器,加载到内存中的类。
为了方便我们理解上面的过程,请看下图的过程。
好了,说过了大概的整体JVM运行流程,我们来具体说下类加载的过程,
先想一个问题:JVM在什么情况下会加载一个类呢?
类加载的过程非常的繁琐复杂,我们在工作中,只要把握住核心的工作原理就可以了,
一个类从加载到使用,一般会经历下面的这个过程:
加载->验证->准备->解析->初始化->使用->卸载
所以,首先我们要搞明白上面的问题,就是JVM在什么情况下回去加载一个类呢?翻译过来就是说,啥时候会从".class"字节码文件中加载这个类到JVM内存中,毕竟,内存是内存是有限的,加载过程很繁琐,也很消耗资源,答案很简单,就是在你的代码中用到这个类的时候去加载。
此时又有问题了,既然是这个类是用到时候去加载,那么如果我在这个类中,用到了多个引用怎么办,就没有个先后顺序么?别担心,这个JVM 早就想到了,他就是类加载机制,双亲委派机制,类加载器都有那些?双亲委派机制又是什么?以及类加载过程中的各个节点都是执行的什么?下一篇详细说