Java虚拟机抽象规范仅仅是个概念,而该规范的具体实现可能来自多个提供商,并存在于多个平台上。它或者完全用软件实现,或者以硬件和软件相结合的方式来实现。
当运行一个java程序的同时,也就在运行一个java虚拟机实例,该虚拟机实例的生命周期就是此程序的生命周期。每个java程序都运行于它自己的java虚拟机实例中。java虚拟机通过调用初始类的main()方法来运行一个java程序,这个mian方法也作为该程序初始线程的起点,任何其他的线程都是由这个初始线程启动的。在java虚拟机中有两种线程:守护线程和非守护线程。守护线程通常是由虚拟机自己使用的,比如收集垃圾的线程。但是java程序也可以把任何线程标记成守护线程。而之前提到的mian方法所在的初始线程是非守护线程。只要还有任何非守护线程运行,那么这个java程序也在继续运行,当该程序的所有非常守护线程都终止时,该程序所在的虚拟机实例将自动退出。
Java虚拟机包含:
- 类装载器子系统:根据给定的权限定名来装入类型(类或接口)
类装载器子系统中可能包含多个类装载器。其中一个必须的是启动类装载器,它是Java虚拟机实现的一部分。另外Java应用程序能够在运行时安装用户自定义的类装载器,这种类装载器能够使用自定义的方式来装载类。由于用户定义类装载器的存在,因而不必再编译的时候就知道运行中的Java应用程序中最终会加入的所有类,从而实现在运行时定制地扩展程序(动态扩展),并动态连接。
- 执行引擎:负责执行那些包含在被装载类的方法中的指令(字节码)
不同的Java虚拟机中,执行引擎的实现各不相同。
- 一次性解释字节码
- 即时编译(just-in-time complier):第一次执行的字节码会被编译成本地机器代码。编译出来的本地机器代码会被缓存,当方法再被调用的时候可以重用。(比方法1快,但更消耗内存)
- 自适应优化器:解释字节码,并监视程序的运行,将使用最频繁的代码段编译成本地代码,其它保留为字节码
- 由硬件芯片构成:用本地方法执行java字节码(内嵌在芯片里)
- 运行时数据区:
每个java虚拟机实例都有一个方法去以及一个堆,它们是由该虚拟机实例中所有线程共享的。方法区中放置从装载的class文件中解析的类型信息。堆中放置该程序运行时创建的对象。
每个新线程被创建时,都将得到自己的pc寄存器以及一个java栈。pc寄存器的值指示下一条将被执行的指令。java栈存储该线程中执行java方法调用的状态(包括局部变量和传入的参数,返回值,运算的中间结果)本地方法栈中存储本地方法调用的状态。