Java虚拟机(二)--java虚拟机的作用和重要组成部分
上文已经提过:一个java虚拟机(后面简称JVM)其实也是一个程序,只不过是由c或c++或汇编编写的平台相关的程序。事实上,在java虚拟机规范中,大多数是宽泛,抽象的规则。这是为了让更多的硬件/操作系统可以自由的实现自己的虚拟机程序。因为毕竟硬件环境/操作系统千差万别。在实现自己的虚拟机程序时,只要符合虚拟机规范中的原则,就能保证其它java程序能顺利的迁移到新的虚拟机平台来。同时又
上文已经提过:一个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程序才成为具备平台无关性的程序。
更多推荐
所有评论(0)