Java虚拟?/strong>
Java虚拟机的主要d是装在class文gq且执行其中的字节码。Java虚拟机包含一个类装蝲器,它可以从E序和API中装载class文g。Java API中只有程序执行时需要的那些cL会被装蝲。字节码由执行引擎来执行?/p>
不同的Java虚拟ZQ执行引擎可能实现得非常不同。在pY件实现的虚拟ZQ最单的执行引擎是一ơ性解释字节码。另一U执行引擎更快,但是也更消耗内存,叫做"x~译?just-in-time compiler)"。在q种情况下,W一ơ被执行的字节码会被~译成本地机器代码。编译出的本地机器代码会被缓存,当方法以后被调用的时候可以重用。第三种执行引擎是自适应优化器。在q种Ҏ(gu)里,虚拟机开始的时候解释字节码Q但是会监视q行中程序的zdQƈ且记录下使用最频繁的代码段。程序运行的时候,虚拟机只把那些活动最频繁的代码编译成本地代码Q其他的代码׃使用得不是很频繁Ql保留ؓ字节?p拟机l箋解释它们。一个自适应的优化器可以使得Java虚拟机在80%~90%的时间里执行被优化过的本C码,而只需要编?0%~20%的对性能有媄响的代码?/p>
当Java虚拟机是׃机操作系l上的Y件实现的时候,JavaE序通过调用本地Ҏ(gu)(native method)和主Z互。Java中有两种Ҏ(gu): JavaҎ(gu)和本地方法。JavaҎ(gu)是由Java语言~写Q编译成字节码文Ӟ存储在class文g中的。本地方法是由其他语a(比如c,c++或汇~语a)~写的,~译成何处理器相关的机器代码。本地方法保存在动态链接库?格式是各个^C有的。运行中JavaE序调用本地Ҏ(gu)Ӟ虚拟载包含这个本地方法的动态库Qƈ调用q个Ҏ(gu)。本地方法是联系JavaE序和底层主机操作系l的q接Ҏ(gu)?/p>
通过本地Ҏ(gu)QJavaE序可以直接讉K底层操作pȝ的资源。一个本地方法接?Java Native Interface, JNI)-使得本地Ҏ(gu)可以在特定主机系l的M一个Javaq_实现上运行?/p>
如果希望使用特定L上的资源Q它们又无法从Java API讉KQ那么可以写一个^台相关的JavaE序来调用本地方法。如果希望保证程序的q_无关性,那么只能通过Java API来访问底层系l资源?/p>
c装载器的体pȝ?/strong>
一个Java应用E序可以使用两种c装载器Q?启动(bootstrap)"c装载器和用户定义的c装载器。启动类装蝲?q是pȝ中唯一?是Java虚拟机实现的一部分。启动类装蝲器通常使用某种默认方式从本地磁盘中装蝲c,包括Java APIc?启动c装载器也被UCؓ原始c装载器、系l类装蝲器或者默认类装蝲??/p>
Java应用E序能够在运行时安装用户定义的类装蝲器,q种c装载器能够使用自定义的方式来装载类。例如,从网l下载class文g。尽启动类装蝲器是虚拟机实现的本质部分Q而用户定义的c装载器不是Q但用户定义的类装蝲器能够用Java来编?能够被编译成class文gQ能够被虚拟载,q能够像其它对象一样实例化?/p>
׃有用户定义类装蝲器,所以不必再~译的时候就知道q行中的Java应用E序中最l会加入的所有的cR用户定义的c装载器使得在运行扩展Java应用E序成ؓ可能。当它运行时Q应用程序能够解军_需要哪些额外的c,能够军_是用一个或是更多的用户定义的类装蝲器来装蝲。由于类装蝲器是用Java~写的,所以用M在Java代码中可以表q的风格来进行类装蝲。这些类可以通过|络下蝲Q可以从某些数据库中获取Q甚臛_以动态生成?/p>
每一个类被装载的时候,Java虚拟机都监视q个c,看到它到底是被启动类装蝲器还是被用户定义c装载器装蝲。当被装载的cd用了另外一个类Ӟ虚拟机就会用装载第一个类的类装蝲器装载引用的cR例如,如果虚拟Z用一个特定的c装载器装蝲Volcanoq个c,它就会用这个类装蝲器装载VolcanocM用的所有类?/p>
׃Java虚拟机采取这U方式进行类的装载,所以被装蝲的类默认情况下只能看到被同一个类装蝲器装载的别的cR通过q种Ҏ(gu)QJava的体pȝ构允许在一个Java应用E序中徏立多个命名空间。运行时的JavaE序中的每一个类装蝲器都有自q命名I间?/p>
Java应用E序可以创徏多少?或多种)被不同的c装载器装蝲的类存放在不同的命名I间中,它们不能怺讉KQ除非应用程序显C地允许q么做。当~写一个Java应用E序的时候,从不同源文g装蝲的类可以分隔在不同的命名I间中。通过q种Ҏ(gu)Q就能够使用Javac装载器的体pȝ构来控制M不同源文件中装蝲的代码之间的怺影响Q特别是能够L恶意代码获取讉K或破坏善意代码的权限?/p>
Web览器是一个动态扩展的例子QW(xu)eb览器用用户定义的c装载器从网l下载用于Java applet的class文g。Web览器用一个用来安装用户定义类装蝲器的Java应用E序。这个用户定义的c装载器通常被称为Java Appletc装载器Q它知道如何向HTTP服务器请求class文g。Java Applet可以作ؓ动态扩展的例子Q因为Java应用E序q不知道它什么时候会开始从|络下蝲览器请求的class文g。只有当览器遇到有Java applet的页面时Q才军_是否需要下载class文g?/p>
Web览器启动的Java应用E序通常为每个提供class文g的网l地址分别创徏不同的用户定义类装蝲器,因此Q不同的用户定义c装载器装蝲不同来源的class文g。这可以把它们分别攄在JavaL应用E序的不同命名空间之下。由于不同来源的Java applet文g攄在不同的命名I间中,恶意的Java applet代码׃会直接访问从别的地方下蝲的class文g。这p够限制或L不同来源的代码之间的怺讉K?/p>
Java class文g
Java class文g主要在^台无x和|络Ud性方面Java更适合|络。它在^台无x方面的d是:为JavaE序提供独立于底层主机^台的二进制Ş式的服务。这U途径途径打破了C或者C++{语a所遵@的传l,使用q些传统语言写的E序通常首先被编译,然后被连接成单独的、专门支持特定硬件^台和操作pȝ的二q制文g。通常情况下,一个^C的二q制可执行文件不能在其他q_上工作。而Java class文g时可以运行在M支持Java虚拟机的gq_和操作系l上的二q制文g?/p>
当编译和q接一个C++E序Ӟ所获得的可执行二进制文件只能在指定的硬件^台和操作pȝ上运行,因ؓq个二进制文件包含了对目标处理器的机器语a。而Java~译器把Java源文件的指o译成字节码Q这U字节码是Java虚拟机的"机器语言"?/p>
class文g设计得紧凑,因此它们可以快速地在网l上传送。其ơ,׃JavaE序是动态连接和动态扩展的Qclass文g可以在需要的时候才下蝲。这个特点得Java应用E序能够安排从网l上下蝲class文g的时_从而可以最大限度地减少l端用户的等待时间?/p>
Java API
Java API通过支持q_无关性和安全性,使得Java适应于网l应用。Java API是运行库的集合,它提供了一套访问主机系l资源的标准Ҏ(gu)。运行JavaE序Ӟ虚拟载程序的class文g所使用的Java API class文g。所有被装蝲的class文g(包括从应用程序中和从Java API中提取的)和所有已l装载的动态库(包含本地Ҏ(gu))共同l成了再Java虚拟Zq行的整个程序?/p>
在一个^台能偶支持JavaE序以前Q必dq个特定q_上明地实现API的功能。ؓ讉KL上的本地资源QJava API调用了本地方法。由于Java API class文g调用了本地方法,JavaE序׃需要再调用它们了。通过q种Ҏ(gu)QJava API class文g为底层主机提供了hq_无关性、标准接口的JavaE序。对JavaE序而言Q无论^台内部如何,Java API都会有同L(fng)表现和可预测的行为。正是由于在每个特定的主机^C明确地实CJava虚拟机和Java API,因此QJavaE序自np够成为具有^台无x的E序?/p>
Java API在Java安全性模型方面也有A(ch)献。当Java API的方法进行Q何有潜在危险的操?比如q行本地盘写操?之前Q都会通过查询讉K控制器来验是否得C授权。访问控制器是一个类Q该cȝ来执行栈验,已决定是否允许某U操作?/p>