虚拟机就像一个公司,运行的每一个Java类就像公司里的一个个员工。想要了解一个员工在公司里一天都干了什么,我们还是先要搞清楚这个公司是什么的。互联网公司?外包公司?皮包公司?
首先看这样几个问题,你是否能回答:
1、Jvm是什么,他安装在哪里,如何做到跨平台的高逼格操作?
2、第一个Java类是怎么加载的?
3、Java虚拟机和main方法是什么关系,执行多个main方法意味着什么?
Jvm 是 Java Virtual Machine 的缩写,即Java虚拟机。
系统虚拟机:对物理计算机的仿真,提供一个可运行的操作系统平台,如Visual Box 、VMware;
程序虚拟机:为运行一个计算机的程序而设计的虚拟机,如Java虚拟机。
如何做到跨平台的呢?
不同的平台对有自己特定的虚拟机,Java虚拟机是Java程序运行在不同平台的中介,这更像是设计模式里的适配器模式,Java虚拟机就是适配器。看看下图,比较直观:
Java虚拟机规范
Java虚拟机的构成、运行都遵循Java虚拟机规范。只要是遵循此规范的java字节码都可以在虚拟机上运行,因此在虚拟机上运行的java字节码并不都是由java语言编译而成的,如Groovy、Scala等生成的Java字节码也可以在Java虚拟机执行。
立足于Java虚拟机可以有不同的跨平台的语言,并且共享Java虚拟机的垃圾回收、即时编译等优良特性。
Java虚拟机规范主要内容有:
大家知道,java程序的入口是一个静态的main方法,例如下面的App.java。那么当我们在执行一个java程序的背后都发生了什么,一起来看看。
public class App { public static void main(String[] args) { System.out.println("Hello World!"); } }
(注意: 本文举例基于windows操作系统)
当我们执行一个java类的时候,主要会经历以下过程:
JVM装载环境配置
在windows系统下,会通过环境配置(如系统环境变量)的JRE路径找到java.exe执行程序,然后装载JVM.dll文件。初始化虚拟机中的函数调用,即通过JVM中的方法调用JVM.dll文件中定义的函数。
解析和验证虚拟机参数
对虚拟机的启动参数进行解析和验证,如最常用堆内存大小设置
-Xmn:设置新生代的大小 -Xms:设置堆的初始值 -Xmx:设置堆的最大值
校验如对垃圾收集器参数设置为:
-XX:+UseSerialGC -XX:+UseParallelGC
则由于UseSerialGC和UseParallelGC不能兼容,JVM启动时会抛出错误信息
创建JVM实例
不管是JVM.dll的装载还是JVM实例的创建,其过程都非常的复杂而且主要由C++ 语言实现(作为java学习者我们暂不做深究,有兴趣的朋友可以自行研究)。
在虚拟机实例的初始化过程中,我们最关心的一步就是他初始化了三个类加载器,用于加载和运行java类,而他们的始祖是由C++ 语言开发的引导类加载器, 也是由此打开了java世界的大门。
类加载机制是面试中常问的知识点,将在本章第三节专题学习
加载主类运行main方法
通过类加载器加载main方法所在的类并执行main方法。
我们一起来解答:回首本节开头的三个问题,你会回答了吗?请留言!