上文已经提过:一个java虚拟机(后面简称JVM)其实也是一个程序,只不过是由c或c++或汇编编写的平台相关的程序。

事实上,在java虚拟机规范中,大多数是宽泛,抽象的规则。这是为了让更多的硬件/操作系统可以自由的实现自己的虚拟机程序。因为毕竟硬件环境/操作系统千差万别。

在实现自己的虚拟机程序时,只要符合虚拟机规范中的原则,就能保证其它java程序能顺利的迁移到新的虚拟机平台来。同时又给虚拟机编写者极大的发挥空间。


一个运行时的java虚拟机实例的天职就是:运行一个java程序。当一个java程序开始的时候,一个虚拟机实例就诞生了。当这个程序运行完成后,虚拟机实例就消亡了。

如果一台计算机上同时运行了3个java程序,那么就会有3个虚拟机实例分别运行它们。

一个JVM从initial class的main()开始执行它所运行的java程序。因此,你必须用implementation-dependent way来告诉虚拟机,initial class的名字。

例如,运行一个名为Echo的java程序:

java Echo Greetings, planet 

java就是操作系统应该运行的java虚拟机的名字,具体看当前运行的是什么虚拟机程序。Echo就是initial class且必须包含main()。剩下的则是程序的输入参数。

下面的话很重要

Inside the Java virtual machine, threads come in two flavors:daemon and non-daemon.

在JVM内部,有两种线程:守护线程和非守护线。守护线程通常是虚拟机自己使用的线程,比如用于垃圾回收的线程。应用程序可以将任意线程标记为守护线程,但是main()所在的线程只能是非守护线程。当一个程序的非守护线程结束时,守护线程就退出了。


虚拟机的组成

前面已经提到,java程序运行时,由虚拟机中的class loader将class文件load到虚拟机的数据结构中,之后由执行引擎(execution engine)执行。

因此接下来要谈到的是class loader, java API, java程序语言。下一节介绍虚拟机的数据结构。


Class Loader

Class loader是虚拟机的一个子系统。事实上,一个虚拟机中可以有多个class loader,分为:

1,启动(bootstrap) class loader-- 虚拟机必须的固有部分。如果虚拟机是c语言编写的,则它也必须用c语言编写。这个class loader在JVM启动时加载java核心API,以满足java程序最基本的需求。

同时还加载用户定义的class loader。

2,用户自定义class loader--可选。用户自定义class loader是由java编写的,需要编译成class文件的程序。load进java虚拟机并像其他类一样被实例化。

用户定义的class loader又分为两类:ExtClassLoader和AppClassLoader。

ExtClassLoader用来加载java的扩展API。

AppClassLoader用来加载用户机器上classpath指定目录中的class文件或jar包,也就是程序员自定义的类。


当运行一个程序时,JVM启动,运行bootstrap class loader ,该class loader加载java核心API,同时加载ExtClassLoader和AppClassLoader。然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载程序员自定义类。


使用用户自定义class loader的意义在于:

1, User-defined class loader senable you to dynamically extend a Java application at run-time. 

2, 安全性

For example, if the virtual machine loads class Volcano through a particular class loader, it will attempt to loadany classesVolcano refers to through the same class loader.在默认情况下,只有同一个class loader装载的类才能相互看到。通过这种行为,你可以实现在单个程序中形成多个name-space。

When you write a Java application, you can segregate classes loaded from different sources into different name-spaces. In this way,you can use Java's class loader architecture to control any interaction between code loaded from different sources.

一个典型的例子:

动态扩展的一个例子就是web浏览器,它使用多个用户定义class loader装载从互联网上下载的多个class文件。

因为,有哪些class文件需要被下载,是由被打开的包含java applets代码的网页,在运行时临时决定的。

浏览器(java程序)一开始并不知道会从互联网上下载什么class文件。

通常情况下,浏览器的java程序会针对每个不同的需要被下载的class文件地址,都创建一个user-defined class loader。

这样每个不同source来的class文件只会在自己的user-defined class loader中,假如其中某个来源的class中包含恶意代码,它也无法影响其他来源的class。


Class file

class文件主要在平台无关性和网络移动性方面使java更适应于网络。java虚拟机是平台相关的,而在它之上的class文件是平台无关的。

同时class文件设计的紧凑,因此它们可以快速的在网络上传送。其次,由于java程序是动态连接和动态扩展的,class文件可以在需要的时候才下载。从而可以最大限度的减少终端用户的等待时间。


Java API

java API是运行库的集合,它提供一套访问主机系统资源的标准方法。编写java程序时,可以假设在任何可运行程序的JVM上都能够获取java API class文件(就是我们运行java程序必须的JRE)。

所有被装载的class文件(包括从应用程序中装载的class文件和从java api中装载的class文件)和所有已经装载的动态库(包含本地方法)共同组成了在JVM上运行的整个程序。

对于java程序而言,无论平台内部如何,java API 都会有同样的表现和可预测的行为。正是由于在每个特定的主机平台上都明确实现了java虚拟机和java API,java程序才成为具备平台无关性的程序。











Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐