具有协作对象的修改后的计算机架构的制作方法

文档序号:6607338阅读:309来源:国知局

专利名称::具有协作对象的修改后的计算机架构的制作方法
技术领域
:本发明涉及计算机,具体而言,涉及一种修改的计算机架构,其使应用程序能够在经由通信网络互连的多个计算机上同时运行。
背景技术
:自从计算机及计算出现以来,所编写的计算机软件是在单个机器上运行的。如图1所示,所示的单个现有技术机器ι包括经由总线4连接至存储器3的中央处理单元CPU2。连接至总线4的还有单个机器1的其他功能单元,如屏幕5、键盘6和鼠标7。对该机器1性能的基本限制在于数据由CPU2来处理,而这些处理结果必须通过总线4来传送。总线4经受很多问题,包括由想要获取对总线的访问的单元所形成的所谓总线“队列”、竞争问题等。在某种程度上,这些问题可通过各种策略来缓解,所述策略包括高速缓冲存储器,但是,这样的策略没有例外地会增加机器1的管理开销。自然,多年来,为了改善机器性能,人们进行了各种尝试。一种方法是使用对称的多个处理器。该现有技术方法已用于所谓的“超级”计算机中,如图2中示意性示出的。这里,多个CPU12连接至全局存储器13。而在CPU12和存储器13间的通信中也出现了瓶颈。该过程被称作“单系统映像”。仅有一个应用以及用于该应用的分布在全局存储器上的存储器的一个完整拷贝。该单个应用可完全透明地从任何存储器位置读取或写入任何存储器位置(即共享)。当存在经由网络互连的多个这样的机器时,这是通过利用针对单个机器编写的单个应用并将所需存储器资源分割成多个部分来实现的。然后,这些部分分布在多个计算机上,以形成可由所有CPU12访问的全局存储器13。该过程依赖于对运行的单个应用程序遮蔽或隐藏所述的存储器分割。当一个机器上的一个CPU必须(经由网络)访问物理上位于不同机器中的存储器位置时,性能会劣化。尽管超级计算机已在获取高计算速率方面在技术上取得了成功,但是其在商业上是不成功的,因为其固有的复杂性使得其制造和管理极其昂贵。特别是,单系统映像的概念从未能够应用于“日用”(大量生产的)计算机和网络。特别是,单系统映像的概念仅仅实际应用于经由很快速的(因此很昂贵的)网络互连的很快速的(同样昂贵的)计算机上。通过使用多个机器来增加计算机能力的另一可能性来自现有技术的分布式计算概念,如图3中示意性所示。在该已知设置中,单个应用程序(Ap)由其作者(或熟悉该应用程序的另一程序员)分割成多个离散任务,以便在例如3个机器上运行,在图3中,η为整数3。这里的意图是,机器Ml...Μ3的每个运行整个应用的不同的三分之一,且意图是使施加于各机器的负载大体相等。所述机器经由网络14来通信,所述网络14可以各种形式来提供,如通信链路、互联网、内联网、局域网等。这种网络14的运行速度一般比各机器Ml、6M2等的每个的总线4的运行速度慢一个量级。分布式计算具有多个缺点。第一,分割应用是一项困难的工作,而且必须人工完成。第二,网络14上的通信数据、部分结果、结果等是一种管理开销。第三,分割的需要使利用更多机器来扩展变得极其困难,因为已分割成例如3部分的应用不能在4个机器上很好地运行。第四,在其中一个机器不能工作时,会实质上降低整个系统的总体性能。另一现有技术设置已知为通过“簇(cluster)”的网络计算,如图4中示意性所示。在该方法中,整个应用被载入每个机器Ml、M2.....Mn上。每个机器都与公共数据库通信,但不与其他机器直接通信。尽管每个机器运行同一应用,但是每个机器进行不同的“工作,,并仅使用其自己的存储器。这有点类似于多个窗口每个均向公众出售火车票。该方法确实可行、可升级,而主要具有的缺点是难以管理网络。在计算机语言如JAVA和MICROSOFT.NET中,有程序员应对的两种主要类型的结构。在JAVA语言中,它们称作对象和类。每次创建对象时,均有称作“<init>”的初始化例程运行。同样,每次加载类时,均有称作“<clinit>”的初始化例程运行。其他语言使用不同的术语,但利用相似的概念。然而,一旦不再需要对象或类时,却没有相当的“清理”或删除例程来删除对象或类。相反地,该“清理”以后台的方式不引人注意地发生。另外,在任何计算机环境中都需要获取和释放锁定(lock),以便能够使用这样的资产、资源或结构,而避免应用程序的不同部分试图同时使用同一资源。在JAVA环境中,这称作同步。在JAVA中,这是通过“monitorenter”和“monitorexit”指令或例程来实现的。其他语言使用不同的术语,但利用相似的概念。
发明内容本发明公开了一种计算环境,其中一个应用程序同时在多个计算机上运行。在这种环境中,需要保证上述初始化、清理和同步过程在所有机器上以一致而协作的方式来运行。该协作目的即是本发明的起源。根据本发明的第一方面,公开了一种多计算机系统,该多计算机系统具有各被编写为仅在单个计算机上运行但却在经由通信网络互连的多个计算机上同时运行的至少一个应用程序,其中创建了同样多个基本相同的对象,每个对象在对应的计算机中,且每个具有基本相同的名称,其中所述相同命名的对象每个的初始内容是基本上相同的,其中,当所述多个计算机的每个不再需要引用其对应的对象时,所有所述相同的对象被全体删除,并且其中,所述系统包括可应用于所有所述计算机的锁定装置,其中想要利用其中的被命名的对象的任一计算机从所述锁定装置获取授权锁定,所述授权锁定允许所述利用,并防止所有其他计算机利用它们对应的被命名的对象,直到所述授权锁定被放弃。根据本发明的第二方面,公开了一种在多个计算机上同时运行至少一个各被编写为仅在单个计算机上运行的应用程序的方法,所述计算机借助于通信网络来互连,所述方法包括下列步骤i)创建同样多个基本相同的对象,每个对象在对应的计算机中,且每个具有基本相同的名称,ii)创建所述的相同命名的对象的每个的初始内容,所述初始内容基本上相同,iii)当所有所述多个计算机不再需要引用其对应的对象时,全体删除所有所述的相同对象,以及iv)要求其中想要利用命名对象的所述计算机中的任何一个去获取授权锁定,该授权锁定允许所述利用,并防止所有其他计算机利用它们的对应的被命名的对象,直到所述授权锁定被放弃。根据本发明的一方面,公开了一种多计算机系统,具有同时运行在多个计算机上的至少一个应用程序,其中所述多个计算机通过通信网络来互连,其中创建同样多个基本上相同的对象,每个所述对象在对应的计算机中且各具有基本上相同的名称,其中每个所述的相同命名的对象的初始内容是基本上相同的,其中当所述多个计算机的每个不再需要引用其对应的对象时,所有所述相同的对象被全体删除,并且其中所述系统包括可应用于所有所述计算机的锁定装置,其中想要利用其中所命名的对象的任何计算机从所述锁定装置获取授权锁定,所述锁定装置允许所述利用,并防止所有其他计算机利用其对应的所命名的对象,直到所述授权锁定被放弃。其中,所述锁定装置包括获取锁定例程和释放锁定例程,且两个例程均包括在对所述应用程序的修改中,其中所述应用程序运行在所有所述计算机上。其中,所述锁定装置进一步包括共享表,该共享表列出由任何所述计算机所使用的所述命名的对象、每个所述对象的锁定状态以及任何未决的锁定获取的队列。其中,所述锁定装置位于不运行所述应用程序并连接到所述通信网络的附加计算机内。其中,每个所述计算机都包括分布式运行时间装置,其中每个所述计算机的分布式运行时间装置能够与所有其他计算机通信,由此如果运行在所述计算机之一上的所述应用程序的部分在该计算机中创建对象,则所创建的对象由所述的一个计算机的分布式运行时间装置传播到所有其他计算机。其中,每个所述计算机都包括分布式运行时间装置,其中每个所述计算机的分布式运行时间装置能够与所有其他计算机通信,由此如果运行在所述计算机之一上的所述应用程序的部分不再需要引用该计算机中的对象,则不被引用的对象的标识由所述的一个计算机的分布式运行时间装置传送至可由所有其他计算机访问的共享表。其中,通过插入初始化例程在加载之前、期间或之后对每个所述应用程序进行修改,以对所述应用程序在其处创建对象的每个实例进行修改,所述初始化例程将一个计算机新创建的每个对象传播到所有所述其他计算机。其中,所述应用程序是根据从下列过程构成的组中所选出的过程来修改的加载时的重新编译、加载前的预编译、加载前的编译、刚好适时的编译、在加载后且在应用程序相关部分执行之前的重新编译。其中,所述被修改的应用程序根据从下列构成的组中所选出的过程被传送到所有所述计算机主/从传送、分支传送和级联传送。其中,分配给所述应用程序或每个所述应用程序的本地存储器容量基本上相同,且对所述应用程序或每个所述应用程序可用的总存储器容量是所述的所分配的存储器容量。其中,所有所述计算机包括分布式更新装置,每个所述分布式更新装置以明显小8于本地存储器读取速率的数据传送速率经由所述通信链路来通信。其中,所述计算机的至少一些由不同制造商制造和/或具有不同的操作系统。根据本发明的另一方面,公开一种在多个计算机上同时运行至少一个应用程序的方法,所述计算机借助于通信网络来互连,所述方法包括下列步骤(i)创建同样多个基本上相同的对象,每个所述对象在对应的计算机中且具有基本上相同的名称,(ii)创建每个所述的相同命名的对象的基本上相同的初始内容,(iii)当所有所述多个计算机不再需要引用其对应的对象时,所有所述的相同对象被全体删除,以及(iv)要求想要利用其中所命名的对象的任何所述计算机获取授权锁定,所述授权锁定允许所述利用,并防止所有其他计算机利用其对应的被命名的对象,直到所述授权锁定被放弃。根据本发明一个实施例的该方法进一步包括下列步骤(V)如果运行在所述计算机之一上的所述应用程序的部分在该计算机中创建对象,则将所创建的对象经由所述通信网络传播到所有其他计算机。根据本发明一个实施例的该方法进一步包括下列步骤(vi)通过插入初始化例程,在加载之前、期间或之后对每个所述应用程序进行修改,以对所述应用程序在其处创建对象的每个实例进行修改,所述初始化例程将一个计算机创建的每个对象都传播到所有所述其他计算机。根据本发明一个实施例的该方法进一步包括下列步骤(Vii)为每个所述计算机提供分布式运行时间装置,以经由所述通信网络在所述计算机之间通信。根据本发明一个实施例的该方法进一步包括下列步骤(Viii)提供可由每个所述分布式运行时间装置访问的共享表,并且其中存储不再要求访问对象的任何计算机的标识、连同该对象的标识。根据本发明一个实施例的该方法进一步包括下列步骤(ix)使计数器装置与所述共享表关联,所述计数器装置存储对不再要求访问所述对象的所述计算机的数量的计数。根据本发明一个实施例的该方法进一步包括下列步骤(x)提供附加计算机,在所述附加计算机上不运行所述的共享程序,并且所述附加计算机容纳所述共享表和计数器,所述附加计算机连接到所述通信网络。根据本发明一个实施例的该方法进一步包括下列步骤(Xi)提供可由每个所述分布式运行时间装置访问的共享表,并且其中存储当前须访问对象的任何计算机的标识、连同该对象的标识。根据本发明一个实施例的该方法进一步包括下列步骤(Xii)使计数器装置与所述共享表关联,所述计数器装置存储对寻求对所述对象的访问的所述计算机的数量的计数。根据本发明一个实施例的该方法进一步包括下列步骤(Xiii)提供附加计算机,所述的共享程序不在所述附加计算机上运行,并且所述附加计算机容纳所述共享表和计数器,所述附加计算机连接到所述通信网络。根据本发明的再一方面,公开了多个计算机,经由通信网络互连,并可操作以保证对在所述多个计算机上同时运行的应用程序的一致的初始化,所述多个计算机被编程来执行如上所述的方法。根据本发明的一个方面,公开了一种多计算机系统,所述多计算机系统具有至少一个应用程序,所述应用程序在通过通信网络互连的多个计算机上同时运行,其中所述应用程序的不同部分基本上同时在所述多个计算机中不同的计算机上执行,其中对于每个所述部分,创建同样多个基本上相同的对象,每个所述对象在对应的计算机中,且其中每个所述计算机的所有读请求仅从读在请求计算机中创建的对象来满足。根据本发明的另一个方面,公开了一种在多个计算机上同时运行至少一个应用程序的方法,所述计算机借助于通信网络来互连,所述方法包括以下步骤(i)在所述计算机中的不同计算机上执行所述应用程序的不同部分,以及对于每个所述部分,创建同样多个基本上相同的对象,所述对象每个在对应的计算机中;以及(ii)通过仅从读在请求计算机中创建的对象来满足每个所述计算机的所有读请求。根据本发明的再个方面,公开了一种单个计算机,被布置为与至少一个其他同样的计算机合作以形成上面所述的多计算机系统。根据本发明的其他方面,公开了一种计算机程序产品,该计算机程序产品包括一组程序指令,该程序指令存储于存储介质中,并可操作以允许多个计算机执行上述方法。下面将参考附图来说明本发明的实施例,在附图中图1示意性示出了传统计算机的内部架构,图2示意性示出了已知的对称多处理器的内部架构,图3示意性示出了现有技术的分布式计算,图4示意性示出了现有技术的利用簇的网络计算,图5是根据本发明第一实施例的多个机器运行同一应用程序的示意性框图,图6示意性示出了设置用于运行JAVA代码并由此构成JAVA虚拟机的现有技术计算机,图7与图6相似,但示出了根据本发明优选实施例的对代码的初始加载,图8与图5相似,但示出了各以图7所示的方式来运行JAVA代码的多个计算机的互连,图9是在将同一应用加载到网络中每个机器上的期间所遵循的过程的流程图,图10的流程图示出了与图9的过程相似的修改的过程,图11示意性示出了利用存储器更新的第一实施例在图8的机器上执行多个线程处理。图12的示意图与图11相似,但示出了另一实施例,图13示出了用于图8的计算机的多线程存储器更新,图14示意性示出了设置用于以JAVA代码运行并由此构成JAVA虚拟机的现有技术计算机,图15示意性示出了运行应用程序并由附加的服务器机器X来提供服务的η个机器,图16的流程图示出了初始化例程的修改,图17的流程图示出了初始化例程的继续或中止,10图18的流程图示出了发送到服务器机器X的问询,图19是服务器机器X对图18的请求作出响应的流程图,图20的流程图示出了针对<clinit>指令的修改的初始化例程,图21的流程图示出了针对<init>指令的修改的初始化例程,图22的流程图示出了“清理”或终结化例程的修改,图23的流程图示出了终结化例程的继续或中止,图24的流程图示出了发送到服务器机器X的问询,图25是服务器机器X对图24的请求作出响应的流程图,图26的流程图示出了monitorenter和exit例程的修改,图27的流程图示出了处理机器在请求获取锁定中所遵循的过程,图28的流程图示出了请求释放锁定,图29是服务器机器X对图27的请求作出响应的流程图,图30是服务器机器X对图28的请求作出响应的流程图,图31示意性示出了互连以同时运行多个应用的两个膝上计算机,其中两个应用在单个计算机上运行,图32的视图与图31相似,但示出了其中在每个计算机上运行一个应用的图31的装置,图33的视图与图31和32相似,但示出了其中两个应用同时在两个计算机上运行的图31的装置。本说明书包括附件A、B、C和D,这些附件提供了实际程序的片段,所述程序的片段可实施所述实施例的各方面。附件A涉及字段,而附件B涉及初始化。附件C涉及终结化。附件D涉及同步。具体实施例方式结合图5,根据本发明的一个优选实施例,单个应用程序50可在经由网络53通信的多个机器Ml、M2...Mn上同时运行。如下文中将变得明显的,机器M1、M2...Mn中的每个在每个机器Ml、M2...Mn上运行同一应用程序50,因此所有机器Ml、M2...Mn均具有相同的应用代码和数据50。同样,机器Ml、M2...Mn中的每个在每个机器Ml、M2...Mn上运行相同的(或基本上相同的)修改器51,因此所有机器Ml、M2...Mn均具有相同的(或基本上相同的)修改器51,其中机器M2的修改器被指定为51/2。此外,在应用50被加载于每个机器Ml、M2...Mn上的过程中,或在应用50在每个机器Ml、M2...Mn上被执行之前,每个应用50已由对应的修改器51根据相同的规则(或基本上相同的规则,因为在每个修改器51/1...51/n内允许小的优化改变)进行了修改。作为上述设置的结果,如果机器Ml、M2...Mn中的每个都具有例如IOMB的共享存储器容量,那么对每个应用50可用的总共享存储器不是如可能所预期的那样为IOnMB,而是仅仅10MB。然而,这如何导致改善的运行将在下文中变得明显。自然,机器Ml、M2...Mn中的每个具有非共享的存储器容量。机器Ml、M2...Mn中的非共享存储器容量一般近似相等,但不一定必须如此。从现有技术已知,通过创建图6中示意性示出的虚拟机以特定应用语言来运行机11器(由不同制造商之一生产,并具有以各种不同的语言之一来运行的操作系统)。图6的现有技术设置具有以Java语言编写并在Java虚拟机61内执行的应用50的形式。因此,当应用想要采用的语言是语言JAVA时,能够运行JAVA代码的JAVA虚拟机就被创建,而不管机器制造商及机器内部细节。更多细节参见美国SUNMicrosystemsInc.的Τ.Lindholm&F.Yellin的“TheJAVAVirtualMachineSpecification”第二版。根据本发明的优选实施例,通过提供如图7所示的方便地称作“分布式运行时间”或DRT71的附加设施,对图6的该公知的现有技术设置进行修改。在图7中,应用50经由分布式运行时间系统71通过箭头75所指的加载过程被加载到Java虚拟机72上。分布式运行时间系统可在分布式计算环境(DCE)名下从开放软件基金会(OpenSoftwareFoundation)获得。特别是,分布式运行时间71在JAVA应用50的箭头75所指的加载过程期间投入运行,以便初始地创建JAVA虚拟机72。加载期间的操作顺序将在下文中结合图9来描述。图8示出了利用JAVA虚拟机的对图5设置的修改形式,所述虚拟机的每个如图7中所示。明显的是,同一应用50再次加载到每个机器Ml、M2...Mn上。但是,由箭头83指示的每个机器Ml、M2...Mn间的通信(尽管通过机器硬件来物理地路由)由每个机器内的各个DRT71/1...71/n来控制。因此,实际上,这可概念化为经由网络73彼此通信的DRT71/1...71/n,而不是机器M1、M2...Mn本身。现在转到图7和图9,在加载过程75期间,对被加载来创建JAVA虚拟机72的程序50进行修改。该修改在图9的90开始,并涉及对正在加载的应用50中的所有存储器位置(JAVA中称作字段-但在其他语言中使用相当的术语)进行检测的初始步骤91。对于步骤92和93中的后续处理需要对这样的存储器位置进行标识。在加载过程75期间,DRT71创建如此标识的所有存储器位置的列表,JAVA字段通过对象和类来列表。易变字段和同步字段二者均被列出。修改过程的下一阶段(图9中标记为92)是在可执行的应用代码中搜索,以便定位每个这样的处理活动,该处理活动对与步骤91所产生的列表对应的字段值进行操作和改变,且因此写入到字段,使得对应存储器位置的值发生改变。当检测到这种改变字段值的操作(典型地为JAVA语言中的putstatic或putfield)时,通过步骤93将“updatingpropagationroutine(更新传播例程)”插入于程序中的该处,以保证将字段值改变通知到所有其他机器。之后,加载过程如图9的步骤94所示以正常方式继续。图10示出了加载期间的初始修改的另一形式。这里,起始和列表步骤90和91以及搜索步骤92与图9中相同。但是,不是如步骤93那样插入“updatingpropagationroutine(更新传播例程),,(其中处理线程执行该更新),而是在步骤103中插入“alertroutine(告警例程)”。"alertroutine(告警例程)”指示未在处理中使用的或被分配给该DRT的一个或多个线程执行必要的传播。该步骤103是一个导致较低开销的较快的替选方法。一旦加载过程期间发生了该初始修改,则发生图11和12中所示的多线程处理操作的任一个。如图11中可见,包含线程111/1...111/4的机器上的多线程处理110正在发生,而第二线程111/2(在该示例中)的处理导致线程111/2在步骤113获知字段值的改变。在该阶段,该线程111/2的正常处理在步骤114被中断,而同一线程111/2经由网络53将在步骤113中发生的被改变的字段的标识和改变的值通知给所有其他机器M2...Mn。在通12信过程的结尾,线程111/2然后在步骤115继续处理,直到发生字段值改变的下一实例。在图12中所示的另一设置中,一旦线程121/2在步骤113获知字段值的改变,其指示DRT处理120(如步骤125和箭头127所示),分配给DRT处理120的另一(或多个)线程121/1要根据步骤128经由网络53将步骤113所检测到的改变的字段的标识和改变的值传播到所有其他机器M2...Mn。该操作可以快速执行,因此,如步骤125所示的,在线程111/2继续步骤115中的处理之前,初始线程111/2的处理仅被瞬时中断。已被通知了所述改变(如箭头127所示)的另一线程121/1然后如步骤128所示经由网络53将该改变传送给每个其他机器M2...Mn。图12的这第二种设置更好地利用了各线程111/1...111/3和121/1的处理能力(一般而言,这些线程并不被同等地要求),而且给予了较好的、具有可增加大小的“η”的缩放性(η是大于或等于2的整数,表示连接至网络53并同时运行应用程序50的机器总数)。不论使用哪种设置,改变的字段和标识及步骤113中所检测的值均被传播到网络上的所有其他机器Μ2...Mn。这示于图13中,其中DRT71/1及图12中的其线程121/1(图13中以步骤128来表示)经由网络53将所列的、在图12的步骤113通过机器Ml中的处理所产生的存储器位置的标识和改变的值传播到每个其他机器Μ2...Mn。通过接收来自网络53的标识和值的对、并将新值写入本地对应的存储器位置中,每个其他机器Μ2...Mn执行图13中步骤135和136所示的针对机器Mn的动作。在利用分布式软件的图3的现有技术设置中,通过互连所述机器的网络,允许从一个机器软件到物理地位于另一机器上的存储器进行访问。但是,这样的存储器访问可导致机器中央处理单元的IO6-IO7个循环的量级的处理延迟。这很大程度上解释了多互连机器的降低的性能。然而,在上述结合图8的本发明的设置中,可以理解的是,数据的所有读取均可在本地得到满足,因为所有字段的当前值均存储在执行该处理的机器上,所述处理产生读取存储器的命令。这样的本地处理可在中央处理单元的IO2-IO3个循环内得到满足。因此,实际上,基本上没有等待包括读取的存储器访问。然而,大多数应用软件频繁地读取存储器,而相对不那么频繁地写入存储器。结果,与存储器被读取的速率相比,写入或重写存储器的速率相对较慢。由于这种对存储器写入或重写的慢的需求,可经由不昂贵的日常网络53以相对低的速度来持续更新字段,但该低速度足以满足应用程序对写入存储器的需求。结果是,图8的设置的性能大大优于图3的性能。在与上述有关的另一实施例中,改变的字段的标识和值可被分组成批,以便进一步降低对互连各机器的网络53的通信速度的要求。对本领域普通技术人员也是明显的是,在由每个DRT71在初始记录字段时所创建的表中,对于每个字段有一个在整个网络中通用的且网络可辨别的名称或标识。但是,在各个机器中,与给定的命名字段对应的存储器位置将随时间变化,因为每个机器将根据其自己的内部进程逐步地在不同位置存储改变的字段值。因此,每个DRT中的表将通常具有不同的存储器位置,而每个全局“字段名称”将具有存储在不同存储器位置中的相同“字段值”。对于本领域普通技术人员来说也明显的是,在加载过程中,应用程序的上述修改可通过下列多至5种方式来完成(i)加载时的重新编译,(ii)在加载前通过预编译过程(iii)加载前的编译(iv)“正好及时(just-in-time)”的编译,或(ν)加载后的重新编译(但是(或例如)在分布式环境中的相关或对应的应用代码执行前)。传统上,术语“编译”隐含代码或语言的改变,例如从源代码到目标代码或一种语言到另一种的改变。在本说明书中清楚的是,术语“编译”(及其语法上的等效)的使用并不如此受限,而亦可包括或包含同一代码或语言内的修改。在第一实施例中,特定的机器,如机器Μ2,将应用代码加载于其自身上,对其进行修改,然后(顺序地或同时)以修改的代码加载每个其他机器Ml、Μ3...Mn。在可称作“主/从”的该设置中,每个机器Ml、M3...Mn加载机器M2所给予的内容。在另一实施例中,每个机器接收应用代码,但在该机器上对其进行修改并加载修改的代码。这使得每个机器执行的修改有些许不同,基于其架构和操作系统被优化,但仍与其他相似的修改是一致的。在另一设置中,特定机器如Ml加载未修改的代码,而所有其他机器M2、M3...Mn进行修改以删除原始应用代码并加载修改的版本。在所有实例中,供给可以有分支(即M2直接供给M1、M3、M4等的每个)或可以是级联或按顺序的(即M2供给Ml,然后Ml供给M3,M3再供给M4,依此类推)。在又一实施例中,机器Ml至Mn可将所有加载请求发送给未运行应用程序的附加机器(未示出),该附加机器通过上述方法的任一种来进行修改,并将修改的例程返回给机器Ml至Mn的每个,然后机器Ml至Mn在本地加载修改的例程。在这种设置中,机器Ml至Mn将所有加载请求发送到该附加机器,该附加机器将修改的例程返回给每个机器。该附加机器进行的修改可包括本发明的范围之内所覆盖的任一修改。计算领域的普通技术人员会知道用于创建计算机代码中的修改的至少4种技术。第一种是以原始(源)语言进行的修改。第二种是将原始代码(如JAVA)转换成中间表示(或中间语言)。一旦发生转换,就进行修改,然后再反向转换。这给出修改的JAVA代码的期望结果。第三种可能性是(直接或经由上述中间语言)转换成机器代码。然后在加载和执行前对机器代码进行修改。第四种可能性是将原始代码转换成中间表示,然后对中间表示进行修改,随后转换成机器代码。本发明涵盖所有4种修改例程,也涵盖2种、3种或甚至4种所述例程的组合。现在转到图4,示出了作为JAVA虚拟机运行的单个现有技术计算机的示意图。以这种方式,(由各制造商的任一个来生产并具有以各种不同语言的任一种来操作的操作系统的)机器能以应用程序50的特定语言来运行,在该实例中为JAVA语言。也就是说,JAVA虚拟机72能够运行JAVA语言的代码50,并利用JAVA架构,而不管机器制造商和机器的内部细节。14在JAVA语言中,初始化例程<clinit>仅在加载给定类文件50A时发生一次。但是初始化例程<init>频繁发生,例如,每次创建新对象50X、50Y和50Ζ时都发生。此外,类是在对象前加载的,这样在图14所示的具有单个类50Α和三个对象50Χ-50Ζ的应用程序中,首先加载第一类50Α,然后加载第一对象50Χ,然后加载第二对象50Υ,最后加载第三对象50Ζ。这里,如图14中所示,仅有单个计算机或机器72,于是要在加载过程期间工作的初始化例程的运行中没有出现冲突或不一致。但是,在图8(还有图31-33)所示的设置中,提供了多个单独的计算机或机器Ml、M2...Mn,其每个经由通信网络53来互连,且其每个被提供有修改器51并加载有普通应用程序50。实质上,修改器51用来复制各机器M1、M2...Mn的每个上的相同存储器结构和内容。因此结果是,在这种计算环境中,有必要保证各机器Ml、M2...Mn的每个以一致的方式来初始化。图5的修改器51的修改功能由图8中的DRT71来提供。为了保证一致的初始化,应用程序50被仔细检查,以便检测定义初始化例程的程序步骤。该仔细检查可在加载前、或加载过程75期间、或甚至在加载过程75之后(但在相关对应的应用代码执行之前)发生。编译过程可这样理解即术语编译通常涉及代码或语言上的改变,如从源代码到目标代码或从一种语言到另一种的改变。但是,在本实例中,术语“编译”(及其语法上的等效)并不受限于此,而是也可包含同一代码或语言中的修改。结果,在上述仔细检查中,初始地查找<clinit>例程,当找到时,插入修改代码(一般是几个指令),以便引起被修改的<clinit>例程的发生。该被修改的例程要将类50A加载到机器之一上,例如JVM#1上,并告知其他机器M2...Mn存在这样的类50A及其当前状态。存在可执行这种修改和加载的几种不同的模式。因此,在一个模式中,加载机器(在本例中是JVM#1)上的DRT71询问所有其他机器的DRT71/2...71/n是否已经初始化了第一类50A。如果对该问题的回答为肯定,则关断或禁止正常的初始化过程。如果回答为否,则进行正常的初始化过程,而且在该过程期间产生的结果的变化将传送给所有其他机器,如图8中的箭头83所示。每次要加载对象如50X、50Y或50Z时会发生相似的过程。如果在调查后DRT71/1没有察觉到正在考虑的特定对象如对象50Υ已经加载到其他机器Μ2...Mn上,那么,DRT71/1运行对象初始化例程,并将等效对象(可方便地称作对等对象)连同初始值的拷贝一起加载到其他机器Μ2...Mn的每个上。但是,如果DRT71/1确定正在考虑的对象50Υ已经存在于其他机器上,则禁止正常的初始化功能,并利用当前值的拷贝来创建本地拷贝。同样,存在用于产生期望结果的各种方式。如图15中所示,提供了对图8的通用设置的修改,其中机器Ml、Μ2...Mn如前所述,并在所有机器Ml、M2...Mn上同时运行同一应用程序(或多个程序)50。但是,以提供服务器机器X的方式对前述设置进行了修改,所述服务器机器X能够方便地提供管家(housekeeping)功能,特别是结构、资产和资源的初始化、清理和/或同步。因为其计算负载低,所以这种服务器机器X可以是低价值的日常计算机,如PC。如图15的虚线所示,为了备份的目的,可提供两个服务器机器X和X+1,以便提高系统的总体可靠性。当提供两个这种服务器机器X和X+1时,它们优选地作为一个簇中的双重机器来工作。如图15的虚线所示,附加机器X+1是可选的。提供服务器机器X不是必须的,因为其计算可以分布在机器Ml、M2...Mn上。可替15换地,一个机器操作的数据库(在主/从型操作中)可用于所述的管家功能。图16示出了初始化所要遵循的优选通用过程。在加载步骤161已经开始后,按照顺序考虑待执行的指令,并检测所有初始化例程,如步骤162所示。在JAVA语言中,这些为<init>和<clinit>例程(或JAVA术语中的方法(method))。其他语言使用不同的术语。当步骤162中检测到初始化例程时,在步骤163中,典型地通过将进一步的指令插入到例程中来对其进行修改。可替换地,可在例程前插入修改指令。一旦完成了修改步骤163,则如步骤164所示,继续加载过程。图17示出了修改的特定形式。在开始步骤171中的例程之后,在步骤172中,给待初始化的结构、资产或资源(在JAVA中称作类或对象)分配名称或标签,这些名称或标签可以被所有机器在全局中使用。这是通过图15的服务器机器X所维护的表来最方便地完成的。该表还包括待初始化的类或对象的状态。如图17所示,如果步骤173和174确定全局名称还未在其他地方(即执行加载的机器以外的机器)初始化,则这意味着由于这是要创建的第一个这种对象或类,因此可通过执行步骤176来以正常方式初始化所述对象或类。但是,如果步骤173和174确定所述全局名称已经在其他地方初始化了,则这意味着另一机器已经初始化了该类或对象。因此,通过执行步骤175,常规初始化例程被完全中止。图18示出了加载机器(Ml、M2...Mn之一)向图15的服务器机器X所作的问询。如步骤181所示,加载机器的操作被暂时中断,直到收到来自机器X的回复,如步骤182所7J\ο图19示出了图15的服务器机器X响应于图18步骤181的这种问询而进行的活动。在步骤192和193中确定初始化状态,如果已经初始化,则通过执行步骤194来将具有该意思的响应发送到问询的机器。同样,如果初始化状态是未初始化,则通过执行步骤195和196来发送对应的回复。然后,通过步骤182来创建的等待的问询的机器能够相应地作出响应。参考附件,其中附件Al-AlO示出与字段相关的实际代码,附件Bl是来自未修改的<clinit>指令的典型代码片段,附件B2是关于修改的<clinit>指令的等效,附件B3是来自未修改的<init>指令的典型代码片段,附件B4是关于修改的<init>指令的等效,此外,附件B5是附件B2的代码的替代,以及附件B6是附件B4的代码的替代。另外,附件B7是InitClient的源代码,其向“初始化服务器(initializationserver)”查询有关类或对象的初始化状态。附件B8是InitServer的源代码,其接收InitClient的初始化状态查询,并作出响应将对应的状态返回。相似地,附件B9是附件B1-B6的实例之前/之后所使用的示例应用的源代码。现在转向图20,示出了修改与类相关的<clinit>例程以便从附件Bl的代码片段转换成附件B2的代码片段的所遵循的过程。在步骤201开始将应用程序50初始加载到JAVA虚拟机72上,通过执行步骤202,仔细检查每行代码,以便检测那些代表<clinit>例程的指令。一旦检测到,通过执行步骤203,如附件B2中所示对<clinit>例程进行修改。如步骤204所示,修改完成后,继续加载过程。附件Bl和B2分别是摘录<clinit>指令之前和之后。添加到该方法(method)中的修改的代码以粗体突出显示。在附件Bl的原始代码样本中,<clinit>方法创建其自己的新对象,并将其写入称作“thisTest”的存储器位置(字段)。因此,在没有分布式环境中的类加载管理的情况下,每个机器将以不同对象来重新初始化同样的共享存储器位置(字段)。显然这不是正加载的应用程序的程序员所期望发生的。因此,利用DRT,通过改变<clinit>方法,在应用代码加载到机器中时对其进行修改。所作的改变(以粗体突出显示)是<clinit>方法执行的初始指令。通过调用isAlreadyLoadedO方法,所添加的这些指令检查该类是否已经加载,isAlreadyLoaded()方法返回与该类的加载状态对应的真或假。DRT的该isAlreadyLoadedO方法可以任选地采用代表该类的唯一标识符的自变量(见附件B5和B6),例如在确定该类的加载状态时将使用的类的名称、或代表该类的类对象、或在所有机器上表示该类的唯一号码。这样,通过使用每个类的唯一标识符来咨询isAlreadyLoaded表中的正确记录,DRT可同时支持多个类的加载,而不会混淆多个类中哪些已加载,哪些未加载。DRT可以多种方式来确定类的加载状态。优选地,如果该类已加载,DRT可依次问询每个机器是否该类已被加载,而如果有任何机器回复真,则返回真,否则返回假。可替换地,本地机器上的DRT可咨询共享的记录表(也许在单独的机器上(如机器X),或咨询本地机器上的一致的共享记录表,或数据库)来确定该类是否已经加载。如果DRT返回假,则这意味着该类以前还未加载到分布式环境中的任何机器上,因此,该执行将视为第一次和原始的。结果,DRT必须将共享记录表中该类的"isAlreadyLoaded"记录更新为真,这样,现在在所有其他机器上,包括当前机器上,isAlreadyLoaded的所有随后的引用均将返回真。因此,如果DRT.isAlreadyLoadedO返回假,则修改的<clinit>方法继续执行原始代码块,其现在跟在被插入的三个指令之后。另一方面,如果DRT返回真,则这意味着该类已经加载于分布式环境中,如被加载的类的共享记录表中所记载的那样。在这种情况下,由于其将覆写已经初始化的存储器位置等,因此不执行原始代码块。因而,当DRT返回真时,所插入的三个指令防止执行原始代码,并直接返回应用程序。图21示出了与对象有关的<init>例程的等效过程,其中步骤212和213相当于图20中的步骤202和203。这导致附件B3的代码被转换成附件B4的代码。针对<clinit>的相似修改也用于<init>。如步骤212所示检测应用程序的<init>块(或多个<init>块,因为可以存在多个,这与<clinit>不同),并如步骤213所示对其进行修改,以便在分布式环境上一致地运转。在附件B3的示例中,应用程序的<init>指令利用加载时间的时间戳来初始化存储器位置(字段)。例如,应用可用此来记录该对象是何时创建的。显然,在对等对象可在不同时间加载的分布式环境中,需要特殊的处理,以保证首先加载的对等对象的时间戳不17被后来的对等对象所覆写。修改发生后的被分解的指令序列示于附件B4中,而且所修改/插入的指令以粗体突出显示。对于<init>修改,与<clinit>修改不同的是,通常要求将修改指令置于“invokespecial”指令之后,而不是在刚开始的位置。这样作的原因是JAVA虚拟机规范所要求的。其他语言经常具有相似的细微的设计差别。测试的基本概念是初始化是否已经执行,如果没有,则进行,如果已经执行,则不再执行进一步的初始化;存在几种可以执行这个概念的不同方式。在第一实施例中,特定机器如机器M2将类或对象加载于其自身上,然后(按顺序或同时地)加载其他机器Ml、M3...Mn的每一个。在该可称作“主/从”的设置中,机器Ml、M3...Mn的每一个加载机器M2所给予的内容。在该“主/从”设置的一种变型中,机器M2将未修改形式的<clinit>例程加载到机器M2上,然后通过整个删除初始化例程来修改该类,并将修改后的类加载到其他机器上。这样,在该实例中,修改不是绕过初始化例程,而是将其从除一个机器以外的所有机器上删除。在又一实施例中,每个机器接收初始化例程,但对其进行修改,并将修改后的例程加载于该机器上。这使得每个机器执行的修改能够有些许不同,基于其架构和操作系统来优化,但是仍然与所有其他相似的修改一致。在又一设置中,特定机器如Ml加载类,而所有其他机器M2、M3...Mn进行修改以删除初始化例程并加载修改后的版本。在所有实例中,供给可以有分支(即M2直接供给M1、M3、M4等的每个)或可以是级联或按顺序的(即M2供给Ml,然后Ml供给M3,M3再供给M4,依此类推)。在又一设置中,初始机器如M2可执行初始加载,然后产生列出机器M2所加载的所有类的表。该表然后(以分支或级联的方式)被发送给所有其他机器。然后,如果除了M2以外的一个机器需要访问所述表中列出的类,则其发送请求给M2,以提供必要的信息。因此,提供给机器Mn的信息通常不同于加载到机器M2中的初始状态。在上述情况下,有必要使表中每个条目附带一个计数器,该计数器在每次加载类时增加。因而,当需要数据时,响应于该需求来传送类内容和对应计数器的计数二者。这种“按要求的(ondemand)”模式增加了每个计算机的开销,但减少了互连计算机的通信网络上的流量。在又一设置中,机器Ml...Mn可将所有加载请求发送给(图15的)附加机器X,该附加机器X通过上述方法中的任一种来执行修改,并将修改后的类返回给机器Ml...Mn的每个,机器Ml...Mn的每个然后在本地加载该类。在这种设置中,机器Ml...Mn不维护任何类的记录表,相反,它们将所有加载请求转发到机器X,机器X维护加载类的表,并根据给定类是否是第一次加载到机器Ml...Mn上,将修改后的类返回给每个机器。机器X进行的修改可包括本发明的范围覆盖的任何修改。再参考图14,在JAVA语言中,初始化例程<clinit>仅在加载给定类文件50A时发生一次。但是初始化例程<init>经常发生,例如,每次创建新对象50X、50Y和50Ζ时都发生。此外,类是在对象之前加载的,这样,在图14所示的具有单个类50Α和三个对象50Χ-50Ζ的应用程序中,首先加载第一类50Α,然后加载第一对象50Χ,然后加载第二对象50Υ,最后18加载第三对象50Z。这里,如图14中所示,仅有单个计算机或机器72,而因为图14的单个机器能够容易地跟踪特定对象50X-50Z将来是否倾向于被需要用于程序50,因此,旨在加载过程期间工作的初始化例程的运行中没有出现冲突或不一致。这是通过维护“handlecount”等来完成的。该计数跟踪可执行代码中对特定对象进行引用之处的数量。当特定对象的handlecount达到0时,在可执行代码中没有对该对象进行引用之处。这于是该对象被称作“可终结化”。一旦达到该状态,由于不再需要,因此可安全地删除(或清理或终结化)该对象。相同的过程将必要的修正(mutatismutandis)施加于类。特别是,计算机程序员在使用JAVA语言和架构来编写程序时,不需要为该清理、删除和终结化编写任何具体代码。相反,单个JAVA虚拟机72可跟踪类和对象的handlecount,并以不引人注意的方式在需要时进行清理(或进行终结化)。但是,在图8(还有图31-33)中所示的设置中,提供了多个单独的计算机或机器M1、M2...Mn,其每个经由通信网络53来互连,且其每个被提供有修改器51(如图5中所示,并通过图8中的DRT71实现)并加载有公共应用程序50。实质上,修改器51或DRT71修改应用代码50,以在多个单独的机器M1、M2...Mn上执行清理例程。因此随之而来的是,使得在这种计算环境中,有必要保证各机器的每个以(关于彼此)一致的方式来终结化。特别地,尽管一个特定机器(如M3)可不再调用一对象或类,但另一机器(如M5)在将来可仍然需要引用该对象和类。因此,如果要从机器M3上删除该对象或类,那么如果M5要写入该对象或修改其值,则由于M3在其本地存储器中没有包括该相关的对象,因此该值的改变就不会传播到所有机器Ml、M2...Mn。另外,如果机器M3要执行对给定对象或类的清理例程,清理例程将不仅针对该机器上的该对象进行清理,而是针对所有其他机器上的对等对象。因而,使得机器M5上的该对象无效。这样,就不会实现同一应用程序的同时运行所要求的、机器Ml、M2...Mn的每个的基本相同的存储器内容的目标。为了保证一致的终结化或清理,应用程序50被仔细检查,以便检测定义清理例程的程序步骤。该仔细检查可在加载前、或加载过程期间、或甚至在加载过程之后(但在应用代码50的相关对应部分的执行之前)发生。编译过程可这样理解即术语编译通常涉及代码或语言上的改变,如从源代码到目标代码或从一种语言到另一种。但是,在本实例中,术语“编译”(及其语法上的等效)并不受限于此,而可包括包含同一代码或语言中的修改。结果,在上述仔细检查中,初始地查找清理例程,当找到时,插入修改代码,以便引起修改后的清理例程的发生。该修改后的例程要在任何特定机器上中止该清理例程,除非所有其他机器均将该待删除的对象或类标记为删除。存在可执行这种修改和加载的几种不同的模式。在这点上,参考附件C,其中阐述了各种清理或终结化的示例。因此,在一种模式中,加载机器(在本例中是JVM#1)上的DRT71/1询问所有其他机器的DRT71/2...71/n例如是否任何其他机器M2.··Mn利用了(即没有标记为删除)第一类50A。如果对该问题的回答为肯定,则针对机器JVM#1上的第一对象50X来关断或禁止正常的清理过程。如果回答为否(即第一对象50X在所有其他机器M2...Mn上标记为删除),则进行正常的清理过程,而且不仅从机器JVM#1上而且从所有其他机器M2...Mn上删除第一对象50X。优选地,该清理任务分配给将对象或类标记为删除的最后的机器Ml。图22示出了关于终结化所遵循的优选通用过程。在开始加载161A之后,待执行的指令按顺序来考虑,并且如在步骤162A中所示地检测所有清理例程。在JAVA语言中,这些是“finalizeO”例程(或JAVA术语中的方法)。其他语言使用不同的术语。当检测到初清理例程时,在步骤163A中,典型地通过将进一步的指令插入到例程中来对其进行修改。可替换地,可在例程之前插入修改指令。一旦完成了修改,则如步骤164A所示,继续加载过程。图23示出了修改的一种特殊形式。首先,如步骤172A中所示,可能是被清理的候选的结构、资产或资源(在JAVA中称作类或对象)50A、50X...50Y,已经被分配了名称或标签,所述名称或标签可由所有机器M1、M2...Mn在全局使用。这优选地发生于对类或对象进行原始初始化时。这是通过服务器机器X所维护的表来最方便地完成的。该表还包括类或对象的“cleanupstatus(清理状态)”。在该优选实施例中,该表还包括存储已经将该资产标记为删除的机器数量的计数的计数器。因此,小于(n-1)的总计数值表示作为网络整体针对该资产的“donotcleanup(不清理)”状态。如图23所示,如果全局名称未在所有其他机器(即除了提请执行清理例程的机器以外)上标记为删除,则如步骤174A所示,这意味着由于仍然需要该对象或类,应该中止所提请的对该对象或类的清理例程。如果全局名称在所有其他机器上标记为删除,则这意味着其他机器不再需要该类或对象。结果可以,并且应该执行步骤176A所示的正常清理例程。图24示出提请执行清理例程的机器(Ml、M2...Mn之一)向服务器机器X所作的问询。如步骤181A和182A所示,该提请的机器的操作被临时中断,直到收到来自机器X的回复,如步骤182A所示。图25示出了机器X响应于这种问询而进行的活动。如步骤192A所示确定清理状态,如果否-指定的资源在(n-1)个机器上未被标记为删除(即在其他地方使用),则带有那个意思的响应被发送到问询的机器194A,而“markedfordeletion(标记为删除)”计数器增一(1),如步骤197A所示。相似地,如果回答为肯定-如步骤195A所示的那样发送对应的回复。等待问询的机器182A然后能够相应地作出响应。如图25中虚线所示,优选地,除了步骤195A中所示的肯定响应之外,还对共享的表进行更新,这样,全局命名的资产的状态变成“清理”,如步骤196A所示。再参考图14,当通过程序员使用同步例程来规定时,图14的单个机器能够容易地执行特定对象50X-50Z的同步。由于每个对象仅在本地存在,图14的单个JAVA虚拟机能够保证对象如程序员规定的那样被正确同步,因此在任何单个时间点仅为可执行代码的一部分来使用。如果另一部分可执行代码希望使用相同的对象,则可能的竞争由JAVA虚拟机这样来解决,也即应用程序的其他执行部分只好等待直到第一部分完成。同一过程对类50A施加必要的修正。特别是,当使用JAVA语言和架构来编写程序时,计算机程序员仅需使用同步例程,以便提供该竞争避免。这样,单个JAVA虚拟机可跟踪多个类和对象的使用,并以不引人注意的方式在需要时避免任何对应的问题。仅一个对象或类被独占地使用的过程称作“同步”。在JAVA语言中,指令“monitorenter”和“monitorexit”表示同步例程的开始和结束,其分别导致对“lock”的获取和释放,所述“lock”防止资产为竞争的主题。但是,在图8(还有图31-33)中所示的设置中,提供了多个单独的计算机或机器M1、M2...Mn,其每个经由通信网络53来互连,且其每个被提供有修改器51(如图5中所示,并通过图8中的DRT71实现)并加载有公共应用程序50。实质上,修改器51或DRT71保证当在一个机器上运行的应用程序50的部分(例如利用同步)独占地使用特定本地资产(如对象50X-50Z或类50A)时,其他机器M2...Mn不在其本地存储器中使用对应的资产。特别地,尽管一个特定机器(如M3)独占地使用一对象或类,但另一机器(如M5)也有可能被其执行的代码指示来在该时独占使用该对象和类。因此,如果该对象或类要被二者独占使用,那么该对象和应用作为一个整体的行为没有定义-也就是说,在对象的正确独占使用没有被程序员明确规定的情况下,可能会导致机器M5和机器M3之间的永久不一致。这样,就不会实现同一应用程序的同时运行所要求的、每个机器Ml、M2...Mn的基本相同的存储器内容的目标。为了保证一致的同步,应用程序50被仔细检查,以便检测定义同步例程的程序步骤。该仔细检查可在加载前、或加载过程期间、或甚至在加载过程之后(但在相关对应的应用代码执行之前)发生。编译过程可这样理解即术语编译通常涉及代码或语言上的改变,如从源到目标代码或从一种语言到另一种。但是,在本实例中,术语“编译”(及其语法上的等效)并不受限于此,而可包括包含同一代码或语言中的修改。参考附件D,其中附件Dl是来自未修改的同步例程的典型代码片段,以及附件D2是关于所修改的同步例程的等效,附件Dl和D2分别在同步例程的摘录之前和之后。添加到该方法的修改代码以粗体突出显示。在附件Dl的原始代码样本中,代码在同步声明内增加共享存储器位置(计数器)。同步声明的目的是为了保证多线程应用中的增量操作的线程安全性。因此,在分布式环境中没有同步管理的情况下,每个机器将在隔离中执行同步,由此有可能同时增加共享的计数器,导致潜在的竞态条件和不一致的存储器。显然这不是应用程序的程序员所期望发生的。因此,利用DRT,通过改变同步例程,在应用代码加载到机器中时被进行修改。所作的修改(以粗体突出显示)是同步例程所执行的初始指令和结束指令。这些添加的指令用于在分布式环境中的所有其他机器上附加地执行同步,由此保持多个机器上应用程序的同步行为。DRT的acquireLock()方法利用表示该对象的唯一标识符的自变量(见附件D2),例如对象名称、正在考虑的对象的引用或在所有节点上表示该对象的唯一号码,以在获得规定对象的全局锁定中使用。这样,通过使用每个对象的唯一标识符来咨询共享同步表中的正确记录,DRT可同时支持多个对象的同步,而不会混淆多个对象的哪个已经同步哪个还没有同步。DRT可以多种方式来确定对象的同步状态。优选地,其可依次问询每个机器其对该对象的本地拷贝当前是否同步,而如果有任何机器回复真,则等待直到该对象不同步,否则在本地对该对象进行同步。可替换地,本地机器上的DRT可咨询共享的记录表(也许在单独的机器上(如机器X),或本地机器上一致的共享记录表,或数据库)来确定该对象是否已经由任何其他机器标记为同步,如果是这样,则等待直到该对象的状态变为“不同步”,然后通过将该对象标记为同步来获得锁定,否则通过由该机器将该对象标记为同步来获得锁21定。如果DRT确定当前没有其他机器具有对该对象的锁定(即没有其他机器已经将该对象同步),则例如通过修改同步状态共享表中的对应条目,或可替换地,通过顺序获得除当前机器以外的所有其他机器上的锁定,在所有其他机器上获得对该对象的锁定。只有当该机器成功确认当前没有其他机器已对该对象同步、并且该机器已在本地对应同步时,原始同步代码块才开始执行。另一方面,如果DRT确定另一机器已经对该对象进行了同步,那么该机器将推迟执行原始同步代码块,直到DRT可确认没有其他机器当前正在执行针对该对象的同步声明而且该机器已经在本地对该对象进行了对应的同步。在这种情况下,将不执行原始代码块,直到该机器可确保没有其他机器正在执行针对该对象的同步声明,原因是,由于竞态条件、存储器不一致将可能引起在参与的机器上损坏该对象,而这同样是同步声明的并发执行所导致的。因此,当DRT确定了该对象当前“已同步”时,DRT通过暂停“acquireLockO”操作的执行来防止原始代码块的执行,直到当前锁定的拥有者执行了对应的“releaseLockO”操作为止。因此,在执行“releaseLockO”操作时,例如通过在同步状态共享表中将该对象标记为“未同步”,或可替换地通过按顺序释放在所有其他机器上获得的锁定,当前“拥有”锁定(即正在执行同步声明)的机器指示其同步声明的结束。在这点,然后,等待开始执行对应的同步声明的任何其他机器可通过继续执行其被推迟(即延迟)的“acquireLockO”操作,例如,在同步状态共享表中将自身标记为执行针对该对象的同步声明,或可替换地在每个其他机器上按顺序获得本地锁定,来要求对该对象的锁定的拥有。这样,利用DRT,通过改变同步例程(包含开始“monitorenter”和结束“monitorexti”指令),在应用代码加载入机器中时对其进行了修改。所作的修改(以粗体突出显示)是同步例程执行的初始指令。这些添加的指令检查该锁定是否已被另一机器获得。如果该锁定尚未被另一机器获得,则该机器的DRT通知所有其他机器该机器已获得锁定,由此停止其他机器执行针对该锁定的同步例程。DRT可以多种方式来记录机器的锁定状态,例如1.对应于同步例程的入口,DRT单独咨询每个机器以确定是否已获得该锁定。如果是,则DRT暂停同步例程的执行,直到所有其他机器不再拥有对该资产或对象的锁定。否则,DRT执行该同步例程。可替换地,2.对应于同步例程的入口,DRT咨询记录的共享表(如共享数据库,或每个参与的机器上的共享表的拷贝),该共享表指示是否有任何机器当前“拥有”该锁定。如果是,则DRT暂停在该机器上执行同步例程,直到所有其他机器不再拥有对该对象的锁定。否则,DRT将该机器记录在共享表中(或者多个共享表中,如果例如在多个机器上存在多个记录表)作为该锁定的拥有者,然后执行同步例程。相似地,当锁定被释放时,换言之,当同步例程的执行结束时,DRT能以很多可替换的方式将机器的锁定状态“去掉记录(un-record)”,例如1.对应于同步例程的出口,DRT单独通知每个其他机器其不再拥有锁定。可替换地,2.对应于同步例程的出口,DRT更新记录共享表中该被锁定的资产或对象的记22录,这样该机器不再被记录成拥有该锁定。另外,DRT能以多种可替换的方式将需要获得锁定对象的机器排队,例如1.对应于同步例程的入口,DRT通知锁定对象的当前拥有者,特定机器欲在当前拥有的机器释放时获得该锁定。如果没有其他等待的机器,则该特定机器将该特定机器的兴趣存储在表中,在该锁定对象的同步例程结束的随后,其通知等待的机器其可获得该锁定对象,因而开始执行其同步例程。2.对应于同步例程的入口,DRT通知该锁定对象的当前拥有者特定机器(如M6)将在该机器(如M4)释放时获取锁定。如果该机器M4在咨询其等待该锁定对象的机器记录后发现已经有一个或多个机器在等待,则将机器M6附于想要获取该锁定对象的机器列表的末尾,或可替换地,将来自M6的请求转发给第一个等待的机器或任何其他等待的机器,所述第一个等待的机器或任何其他等待的机器又将机器M6记录在它们的记录表中。3.对应于同步例程的入口,DRT将自身记录在记录共享表中(例如,存储在可由所有机器访问的共享数据库中的表、或基本上相似的多个单独的表)。另外,对应于同步例程的出口,DRT可通知其他排队的机器由该机器以下列可替换的方式来获取该锁定,例如1.对应于同步例程的出口,DRT通知正在等待的机器之一(例如,正在等待的机器队列中的该第一个机器)该锁定已释放,2.对应于同步例程的出口,DRT通知正在等待的机器之一(例如,正在等待的机器队列中的该第一个机器)该锁定已释放,此外,提供整个机器队列的拷贝(例如,等待该锁定的第二个机器和随后的机器)。这样,第二个机器从第一个机器继承正在等待的机器的列表,并由此在列表中每个机器依次获得并随后释放该锁定时,保证正在等待的机器队列的连续性。在上述仔细检查期间,初始地查找“monitorenter”和“monitorexit”指令(或方法),并且当找到时,插入修改的代码,以得到修改后的同步例程。该修改后的同步例程获取并释放锁定。.执行这种修改和加载的有几种不同的模式。附件D提供了进一步的信肩、ο图26示出了关于同步的所要遵循的优选一般过程。在开始加载161B后,如步骤162B所示,按顺序考虑待执行的指令,并检测所有的同步例程。在JAVA语言中,这些是"monitorenter”和“monitorexit”指令。其他语言使用不同的术语。在检测到同步例程之处,典型地通过将进一步的指令插入例程中对其进行修改。可替换地,修改的指令可插入在例程前。一旦完成修改,则继续加载过程。如步骤163B所示,所述修改优选地采用“acquirelockonallothermachines(在所有机器上获取锁定)”操作和“releaselockonallothermachines(在所有机器上释放锁定)”修改的形式。图27示出了修改的特定形式。首先,如步骤172B所示,待同步的结构、资产或资源(在JAVA中称作类或对象,如50A、50X-50Y)已被分配名称或标签,所述名称或标签可由所有机器在全局使用。这优选地在初始地对类或对象进行初始化时发生。这通过服务器机器X所维持的表十分方便地完成。该表还包括类或对象的同步状态。在优选实施例中,该表还包括存储已请求使用该资产的机器标识的队列设置。如图27的步骤173B所示,接下来,“acquirelock”请求被发送到机器X,之后,如步骤174B中所示,发送机器等待对锁定获取的确认。因此,如果全局名称已经被锁定(即对应资产正在被另一机器而不是提请获取该锁定的机器所使用),则这意味着所提请的对象或类的同步例程应该暂停,直到该对象或类被当前拥有者解锁。可替换地,如果全局名称未被锁定,则这意味着没有其他机器正在使用该类或对象,而且立即接收到对锁定获取的确认。在收到对锁定获取的确认后,如步骤175B所示,允许继续执行同步例程。图28示出了想要放弃锁定的应用程序执行机器所遵循的过程。步骤181B指示了初始步骤。该提请的机器的操作由步骤183B、步骤184B临时中断,直到对应于步骤184B,收到来自机器X的回复,然后如步骤185B所示继续执行。任选地,且如步骤182B所示,使请求释放锁定的机器在向机器X作出请求之前查询该锁定的“globalname(全局名称)”。这样,可获取并释放多个机器上的多个锁定,而不会彼此干扰。图29示出了机器X响应于(图27的/‘acquirelock”问询而进行的活动。当在步骤191B接收到“acquirelock”请求后,在步骤192B和193B确定锁定状态,如果否-所指定的资源不空闲,在步骤194B将问询的机器的标识添加到等待获取请求的队列(或以问询的机器的标识来形成等待获取请求的队列)。可替换地,如果回答是肯定的_所指定的资源空闲_则在步骤197B发送对应的回复。然后,等待的问询的机器能够通过执行图27的步骤175B来相应地执行同步例程。除了肯定响应以外,还在步骤196B更新共享表,以使全局命名的资产的状态改变成“locked(锁定)”。图30示出了机器X响应于图28的“releaselock”请求而进行的活动。当在步骤201接收到“releaselock"请求后,如步骤202所示,机器X可选地并优选地确认所述请求释放锁定的机器正是该锁定的当前拥有者。接下来,在步骤203确定队列状态,如果没有机器正在等待获取该锁定,则如步骤207所示,机器X在共享表中将该锁定标记为“unowned(未被拥有)”,并如步骤208所示,可选地将对释放的确认发送回请求的机器。这使请求的机器能够执行图28的步骤185B。可替换地,如果肯定_即有其他机器正在等待获取该锁定_则如步骤204所示,机器X将该锁定标记为现在由队列中的下一机器获取,然后在步骤205将对锁定获取的确认发送到该排队的机器,并因此如步骤206所示,将新锁定拥有者从等待机器的队列中去除。现在转到图31-33,其中示出了两个膝上计算机101和102。计算机101和102不必是相同的,并且实际上,一个可以是IBM或IBM-克隆,而另一个可以是Apple计算机。计算机101和102具有两个屏幕105、115,两个键盘106、116,但只有单个鼠标107。两个机器101、102借助于单个同轴线缆或双绞线线缆314来互连。两个简单的应用程序被下载到机器101、102的每个上,如上所述,所述程序在其被加载时得到修改。在该实施例中,第一应用是简单的计算器程序,并导致计算器108的图像显示在屏幕105上。第二程序是图形程序,其显示在矩形框310内随机移动的4个不同颜色的彩色块109。同样,在加载后,框310显示在屏幕105上。每个应用独立运行,这样块109在屏幕105上随机运动,而同时可选择(利用鼠标107)计算器108内的数字连同数学运算符(如加法或乘法),使得计算器108显示结果。鼠标107可用来“抓取”框310,并将其移动到右边跨过屏幕105到屏幕115上,以达到图32中所示的情形。在该设置中,计算器应用在机器101上执行,而引起框310的显示的图形应用在机器102上执行。但是,如图33所示,可以借助于鼠标来将计算器108拖到右边,如图32中所示,以便使计算器108的一部分分别由屏幕105、115来显示。相似地,可借助于鼠标107将框310拖到左边,如图32中所示,以使框310部分显示在屏幕105、115的每个上,如图33中所示。在该配置中,部分计算器操作在机器101上执行,而部分在机器102上执行,同时部分图形应用在机器101上进行,而剩余的在机器102上进行。上文仅描述了本发明的某些实施例,而对本领域普通技术人员显而易见的是,可在不背离本发明范围的情况下对其进行修改。例如,对JAVA的引用可包括JAVA语言,还可包括JAVA平台和架构。编程领域的普通技术人员将意识到,当附加代码或指令插入现有代码或指令集中以对其进行修改时,现有代码或指令集会需要进一步的修改(如通过对顺序的指令重新编号),以便满足偏移、分支、属性和标记等。相似地,在JAVA语言中,存储器位置包括例如字段和数组类型二者。以上描述讨论了字段,而数组类型所需的改变基本上也是同样必要的修正。本发明还可同等地应用于与JAVA相似的(包括过程式、宣告式和面向对象的)编程语言,包括Micrsoft.NET平台和架构(VisualBasic、VisualC/C++和C#)FORTRAN、C/C++、COBOL、BASIC等其中修改了JAVA初始化例程代码的上述实施例基于这样的假设即每个机器Ml...Mn的运行时间系统(S口以C和JAVA编写的JAVAH0TSP0TVIRTUALMACHINE)或操作系统(例如以C和汇编语言编写的LINUX)将调用JAVA初始化例程。可以不修改JAVA初始化例程,而是对调用JAVA初始化例程的LINUX或H0TSP0T例程进行修改,这样,如果已经加载了对象和类,则不调用JAVA初始化例程。为了包含这样的设置,术语“初始化例程”应理解为在其范围内包括JAVA初始化例程以及JAVA初始化例程和调用或发起JAVA初始化例程的LINUX或H0TSP0T代码片段的“组合”二者。其中修改了JAVA终结化或清理例程代码的上述实施例基于这样的假设即每个机器M1、M2...Mn的运行时间系统(即以C和JAVA编写的JAVAH0TSP0TVIRTUALMACHINE)或操作系统(例如以C和汇编语言编写的LINUX)将调用JAVA终结化例程。可以不修改JAVA终结化例程,而是对调用JAVA终结化例程的LINUX或H0TSP0T例程进行修改,这样,如果不要删除对象和类,则不调用JAVA终结化例程。为了包含这样的设置,术语“终结化例程”应理解为在其范围内包括JAVA终结化例程以及JAVA终结化例程和调用或发起JAVA终结化例程的LINUX或H0TSP0T代码片段的“组合”二者。其中修改了JAVA同步例程代码的上述实施例基于这样的假设即每个机器Ml、M2...Mn的运行时间系统(SP以C和JAVA编写的JAVAH0TSP0TVIRTUALMACHINE)或操作系统(例如以C和汇编语言编写的LINUX)将在本地机器(如M2)而不是在任何其他机器(Ml、M3...Mn)上正常获取锁定。可以不修改JAVA同步例程,而是对在本地获取锁定的LINUX或H0TSP0T例程进行修改,这样,其对应地在所有其他机器上获得锁定。为了包含这样的设置,术语“同步例程”应理解为在其范围内包括JAVA同步例程以及JAVA同步例程和执行锁定获取和释放的LINUX或H0TSP0T代码片段的“组合”二者。在此使用的术语对象和类是从JAVA环境中导出的,且旨在包含从不同环境如动态链接库(DLL)或目标代码包或功能单元或存储器位置导出的相似术语。在此所用的术语“包括”(及其语法上的变型)是“具有”或“包含”的包含性的意义,而不是“仅由......来构成”的“排他性”的意义。版权须知该专利说明书包含受版权保护的材料。版权的所有者(即申请人)不反对为了评论的目的从公众可获得的相关专利局文件中复制该专利说明书或相关材料,但是保留所有的版权。特别是,在没有版权所有者的特别书面许可的情况下,不得将各指令输入计算机中。附件A下面是JAVA语言的程序列表Al.该第一摘录是修改代码的部分。其在整个代码阵列中搜索,并且在找到putstatic指令(opcode178)时,其实施所述修改。//STARTbyte[]code=Code_attribute.code;//Bytecodeofagivenmethodina//givenclassfile.intcode_length=Code_attribute.code_length;intDRT=99;//LocationoftheCONSTANTMethodref一infoforthe//DRT.alert()method.for(inti=0;i<code_length;i++){if((code[i]&0xff)==179){//Putstaticinstruction.System,arraycopy(code,i+3,code,i+6,code_length_(i+3));code[i+3]=(byte)184;//Invokestaticinstructionforthe//DRT.alert()method.code[i+4]=(byte)((DRT>>>8)&0xff);code[i+5]=(byte)(DRT&Oxff);}}//ENDA2.该第二摘录是DRT.alert()方法的部分。这是DRT.alert()方法被调用时的主体。//STARTpublicstaticvoidalert(){synchronized{ALERT_L0CK){ALERTLOCK,notify();//AlertsawaitingDRTthreadinthebackground.}}//ENDA3.该第三摘录是DRTSending的部分。该代码片段示出了DRT在得到通知后在26单独线;程中跨网络地发送值。//STARTMulticastSocketms=DRT.getMulticastSocket();//Themulticastsocket//usedbytheDRTfor//communication.bytenameTag=33;//Thisisthe"nametag"onthenetworkforthis]//field.Fieldfield=modifiedClass.getDeclaredField(“myFieldl");IlStores//thefield//fromthe//modified//class.//Inthisexample,thefieldisabytefield.while(DRT.isRunning()){synchronized(ALERT_L0CK){ALERT_L0CK.waitQ;//TheDRTthreadiswaitingforthealert//methodtobecalled.byte[]b=newbyte[]{nameTag,field.getByte(null)};//Stores//the//nameTag//andthe//value//ofthe//fieldfrom//themodified//classina//buffer.DatagramPacketdp=newDatagramPacket(b,0,b.length);27ms.send(dp);//Sendthebufferoutacrossthenetwork.}}//ENDA4.第四摘录是DRTreceiving的部分。这是接收DRT在网络上发送的告警的代码片段。//STARTMulticastSocketms=DRT.getMulticastSocket();//Themulticastsocket//usedbytheDRTfor//comunication.DatagramPacketdp=newDatagramPacket(newbyte[2],0,2);bytenameTag=33;//Thisisthe"nametag"onthenetworkforthis//field.Fieldfield=modifiedClass.getDeclaredField("myFieldl");//Storesthe//fieldfrom//themodified//class.//Inthisexample,thefieldisabytefield.while(DRT.isRunning){ms.receive(dp);//Receivethepreviouslysentbufferfromthenetwork.byte[]b=dp.getDataO;if(b==nameTag){//Checkthenametagsmatch.field.setByte(null,b[l]);//Writethevaluefromthenetworkpacket//intothefieldlocationinmemory.A5.第五摘录是发生修改前的示例应用。MethodvoidsetValues(int,int)0iload_l1putstatic#3<FieldintstaticValue>4aload_05iload_26putfield#2<FieldintinstanceValue>9returnA6.第六摘录是与5中相同的示例应用已经执行修改后的情形。修改以粗体突出显不。MethodvoidsetValues(int,int)0iload」1putstatic#3〈FieldintstaticValue>4ldc#4〈String"example">6iconst—07invokestatic#5〈Methodvoidalert(java.lang.Object,int)>10aload—011iload—212putfield#2〈FieldintinstanceValue>15aload—016iconst—117invokestatic#5〈Methodvoidalert(java.lang.Object,int)>20returnA7.第七摘录是摘录5和6中所用的示例应用的源代码。importjava.lang.女;publicclassexample{/女女Sharedstaticfield.女/publicstaticintstaticValue=0;,/女女Sharedinstancefield.女/publicintinstanceValue=0;/**Examplemethodthatwritestomemory(instancefield).*/publicvoidsetValues(inta,intb){staticValue=a;instanceValue=b;ιιA8.第八摘录是FieldAlert的源代码,其告警“distrubutedruntime,,以传播改变的值。importjava.lang.·;importjava.util.~k;importjava.net.~k;importjava.io.~k;publicclassFieldAlert{/**Tableofalerts.*/publicfinalstaticHashtablealerts=newHashtable();/**Objecthandle.*/publicObjectreference=null;/**Tableoffieldalertsforthisobject.*/publicboolean[]fieldAlerts=null;/**Constructor.*/publicFieldAlert(Objecto,intinitialFieldCount){reference=ο;fieldAlerts=newboolean[initialFieldCount];}/-k-kCalledwhenanapplicationmodifiesavalue.(Bothobjectsandclasses)*/publicstaticvoidalert(Objecto,intfieldID){//Lockthealertstable.synchronized(alerts){FieldAlertalert=(FieldAlert)alerts,get(o);if(alert==null){//Thisobjecthasn'tbeenalertedalready,//soaddtoalertstable.alert=newFieldAlert(o,fieldID+1);alerts,put(o,alert);}if(fieldID>=alert.fieldAlerts.length){//0k,enlargefieldAlertsarray.boolean[]b=newboolean[fieldID+1];System,arraycopy(alert.fieldAlerts,0,b,0,alert.fieldAlerts.length);alert.fieldAlerts=b;}//Recordthealert.alert.fieldAlerts[fieldID]=true;//Markaspending.FieldSend.pending=true;//Signalthatthereisoneormore//propagationswaiting.//Finally,notifythewaitingFieldSendthread(s)if(FieldSend.waiting){FieldSend.waiting=false;alerts,notify();}}}}Α9·第九摘录是FieldSend的源代码,其将通过FieldAlert告警给其的改变的值传播。importjava.lang.~k;importjava.lang.reflect.~k;importjava.util.~k;importjava.net.~k;importjava.io.~k;publicclassFieldSendimplementsRunnable{/**Protocolspecificvalues.*/publicfinalstaticintCLOSE=一1;publicfinalstaticintNACK=0;publicfinalstaticintACK=1;publicfinalstaticintPROPAGATEOBJECT=10;publicfinalstaticintPROPAGATECLASS=20;/**FieldAlertnetworkvalues.*/publicfinalstaticStringgroup=System.getProperty("FieldAlert—netwotk—group");publicfinalstaticintport=Integer,parselnt(System.getProperty(“FieldAlert—network—port‘‘));/女女TableofglobalID/sforlocalobjects.(hashcode-to-globalIDmappings)*/publicfinalstaticHashtableobjectToGloballD=newHashtable();/^k^kTableofglobalID'sforlocalc1assnames.(classname-to-globalIDmappings)*/publiefinalstaticHashtablecIassNameToGlobalID=newHashtable()/女女Pending.Trueifapropagationispending.女/publicstaticbooleanpending=false;/**Waiting.TrueiftheFieldSendthread(s)arewaiting.*/publicstaticbooleanwaiting=false;/^k^kBackgroundsendthread.Propagatesvaluesasthisthreadisalertedtotheiralteration.*/publicvoidrun(){System,out.println(/rFieldAlert—network—group=〃+group);System,out.println(/rFieldAlert—network—port=〃+port);31try{//CreateaDatagramSockettosendpropagatedfieldvalues.DatagramSocketdatagramSocket=newDatagramSocket(port,InetAddress.getByName(group));//Next,createthebufferandpacketforalltransmissions.byte[Jbuffer=newbyte[512];//Workinglimitof512bytes//perpacket.DatagramPacketdatagramPacket=newDatagramPacket(buffer,0,buffer,length};while(!Thread,interrupted()){Object[!entries=null;//Lockthealertstable.synchronized(FieldAlert.alerts){//Awaitforanalerttopropagatesomething.while(!pending){waiting=true;FieldAlert.alerts,wait();waiting=false;}pending=false;entries=FieldAlert.alerts.entrySet().toArray();//Clearalertsoncewehavecopiedthem.FieldAlert.alerts,clear();}//Processeachobjectalertinturn.for(inti=0;i<entries,length;i++){FieldAlertalert=(FieldAlert)entries[i];intindex=0;datagramPacket.setLength(buffer,length);Objectreference=null;if(alert,referenceinstanceofString){//PROPAGATE—CLASSfieldoperation.buffer[index++]=(byte)((PROPAGATECLASS>>24)&0xff)buffer[index++]=(byte)((PROPAGATECLASS>>16)&0xff)buffer[index++]=(byte)((PROPAGATECLASS>>8)&0xff)buffer[index++]=(byte)((PROPAGATECLASS>>0)&0xff)Stringname=(String)alert,reference;intlength=name,length();buffer[index++]=(byte)((length>>24)&0xff);buffer[index++]=(byte)((length>>16)&0xff);buffer[index++]=(byte)((length>>8)&0xff);buffer[index++]=(byte)((length>>0)&0xff);byte[]bytes=name.getBytes();System,arraycopy(bytes,0,buffer,index,length);index+=length;}else{//PROPAGATEOBJECTfieldoperation.buffer[index++]=(byte)((pROPAGATEOBJECT>>24)&0xff);buffer[index++]=(byte)((PROPAGATEOBJECT>>16)&0xff);buffer[index++]=(byte)((PROPAGATEOBJECT>>8)&0kff);buffer[index++]=(byte)((PROPAGATEOBJECT>>0)&0xff);intglobalID=((Integer)objectToGloballD.get(alert,reference)).intValue();buffer[index++]=(byte)((globalID>>24)&0xff);buffer[index++]=(byte)((globalID>>16)&0xff);buffer[index++]=(byte)((globalID>>8)&0xff);buffer[index++]=(byte)((globalID>>0)&0xff);reference=alert,reference;}//Usereflectiontogetatableoffieldsthatcorrespondto//thefieldindexesusedinternally.Field[]fields=null;if(reference==null){fields=FieldLoader.IoadClass((String)alert,reference).getDeclaredFields();}else{fields=alert,reference.getClass().getDeclaredFields();}//NowencodeinbatchmodethefieldlD/valuepairs.for(intj=0;j<alert.fieldAlerts.length;j++){if(alert.fieldAlerts[j]==false)continue;buffer[index++]=(byte)((j>>24)&0xff);buffer[index++]=(byte)((j>>16)&0xff);buffer[index++]=(byte)((j>>8)&0xff);buffer[index++]=(byte)((j>>0)&0xff);33//Encodevalue.Classtype=fields[j].getType();if(type==Boolean.TYPE){buffer[index++]=(byte)(fields[j].getBoolean(reference)?1:0);}elseif(type==Byte.TYPE){buffer[index++]=fields[j].getByte(reference);}elseif(type==Short.TYPE){shortν=fields[j].getshort(reference);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Character.TYPE){charν=fields[j].getChar(reference);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Integer.TYPE){intν=fields[j].getlnt(reference);buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Float.TYPE){intν=Float,fIoatToIntBits{fields[j].getFloat(reference));buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Long.TYPE){longν=fields[j].getLong(reference);buffer[index++]=(byte)((v>>56)&0xff);buffer[index++]=(byte)((v>>48)&0xff);buffer[index++]=(byte)((v>>40)&0xff);buffer[index++]=(byte)((v>>32)&0xff);buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}elseif(type==Double.TYPE){34type.改变的值longν=Double.doubleToLongBits(fields[j].getDouble(reference))buffer[index++]buffer[index++]buffer[index++]buffer[index++]=(byte)((v>>56)&0xff)=(byte)((v>>48)&0xff)=(byte)((v>>40)&0xff)=(byte)((v>>32)&0xff)buffer[index++]=(byte)((v>>24)&0xff);buffer[index++]=(byte)((v>>16)&0xff);buffer[index++]=(byte)((v>>8)&0xff);buffer[index++]=(byte)((v>>0)&0xff);}else{thrownewAssertionError("Unsupported//Nowsetthelengthofthedatagrampacket.datagramPacket.setLength(index);//Nowsendthepacket.datagramSocket.send(datagramPacket);}catch(Exceptione){thrownewAssertionError('Exception"+e.toString())A10.第十摘录是FieldReceive的源代码,其接收经由FieldSend发送的所传播的-kimportjava.lang.~k;importjava.lang.reflect,importjava.util.~k;importjava.net.~k;importjava.io.~k;publicclassFieldReceiveimplementsRunnable{■k//**Protocolspecificvalues.publicfinalstaticintCLOSE=publicfinalstaticintNACK=)publicfinalstaticintACK=1port‘’publicfinalstaticintPR0PAGATE_0BJECT=10;publicfinalstaticintPROPAGATECLASS=20;/**FieldAlertnetworkvalues.*/publicfinalstaticStringgroup=System.getProperty(〃FieldAlert_network_group");publicfinalstaticintport=Integer,parselnt(System.getProperty("FieIdAlert_network_))/TableofglobalID/sforlocalobjects.(globalID-to-hasbcodemappings)*/publicfinalstaticHashtableglobalIDToObject=newHashtable();/女女TableofglobalID'sforlocalclassnames.(globalID-to-classnamemappings)*/publicfinalstaticHashtableglobalIDToClassName=newHashtable();/女女Calledwhenanapplicationistoacguirealock.女/publicvoidrun(){System,out.println("FieldAlert—network—group-"+group);System,out.println(/rFieldAlert—network—Port="+port);try{//CreateaDatagramSockettosendpropagatedfieldvaluesfromMulticastSocketmulticastSocket=newMulticastSocket(port);multicastSocket.joinGroup(InetAddress.getByName(group));//Next,createthebufferandpacketfor.alltransmissions.byte[Jbuffer=newbyte[512];//Workinglimitof512//bytesperpacket.DatagramPacketdatagramPacket=newDatagramPacket(buffer,O,buffer.length);while(!Thread,interrupted()){//Makesuretoresetlength.datagramPacket.setLength(buffer,length);//Receivethenextavailablepacket.multicastSocket.receive(datagramPacket);intindex=0,length=datagramPacket.getLength();//Decodethecommand.intcommand=(int)(((buffer[index++]&0xff)<<24)I((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)36(buffer[index++]&0xff));if(command==PROPAGATEOBJECT){//Propagateoperationfor.//objectfields.//Decodeglobalid.intglobalID=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));//Now,needtoresolvetheobjectinquestion.Objectreference=globalIDToObject.get(newInteger(globalID));//Next,getthearrayoffieldsforthisobject.Field[]fields=reference.getClass().getDeclaredFields();while(index<length){//Decodethefieldid.intfieldID=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));//Determinevaluelengthbasedoncorrespondingfield//type.Fieldfield=fields[fieldID];Classtype=field.getType();if(type==Boolean.TYPE){booleanν=(buffer[index++]==1true:false);field.setBoolean(reference,v);}elseif(type.==Byte.TYPE){byteν=buffer,[index++];field.setByte(reference,v);}elseif(type==Short.TYPE){shortν=(short)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setShort(reference,v);}elseif(type==Character.TYPE){charν=(char)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setChar(reference,v);}elseif(type==Integer.TYPE){intν=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setlnt(reference,v);}elseif(type==Float.TYPE){intv=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setFloat(reference,Float.intBitsToFloat(v));}elseif(type==Long.TYPE){longν=(long)(((buffer[index++]&0xff)<<56)((buffer[index++]&0xff)<<48)((buffer[index++]&0xff)<<40)((buffer[index++]&0xff)<<32)((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setLong(reference,v);}elseif(type==Double.TYPE){longν=(long)(((buffer[index++]&0xff)<<56)((buffer[index++]&0xff)<<48)((buffer[index++]&0xff)<<40)((buffer[index++]&0xff)<<32)((buffer[index++]&0xff)<<24)I((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setDouble(reference,Double.IongBitsToDouble(v)};}else{thrownewAssertionError("Unsupportedtype.");}}}elseif(command==PROPAGATECLASS){//Propagateanupdate//toclassfields.//Decodetheclassname.intnameLength=(int)(((buffer[index++]&0xff)<<24)I((buffer[index++]&0xff)<<16)I((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));Stringname=newString(buffer,index,nameLength);index+=nameLength;//Next,getthearrayoffieldsforthisclass.Field[]fields=FieldLoader.IoadClass(name).getDeclaredFields();//Decodeallbatchedfieldsincludedinthispropagation//packet.while(index<length){//Decodethefieldid.intfieldID=(int)(((buffer[index++]&0xff)<<24)((buffer[index++].&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));//Determinefieldtypetodeterminevaluelength.Fieldfield=fields[fieldID];Classtype=field.getType();if(type==Boolean.TYPE){booleanν=(buffer[index++]==1?true:false);field.setBoolean(null,v);}elseif(type==Byte.TYPE){byteν=buffer[index++];field.setByte(null,v);}elseif(type==Short.TYPE){shortν=(short)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field.setShort(null,ν);}elseif(type==Character.TYPE){charν=(char)(((buffer[index++]&0xff)<<8)(buffer[index++]&0xff)};field.setChar(null,ν);}elseif(type==Integer.TYPE){intν=(int)(((buffer[index++]&0xff)<<24)((buffer[index++]&0xff)<<16)((buffer[index++]&0xff)<<8)(buffer[index++]&0xff));field,setlnt(null,ν);}elseif(type==Float.TYPE){390730]intν=(int)(((buffer[index++]&0xff)<<24)0731]((buffer[index++]&0xff)<<16)0732]I((buffer[index++]&0xff)<<8)0733](buffer[index++]&0xff));0734]field.setFloat(null,Float.intBitsToFloat(v));0735]}elseif(type==Long.TYPE){0736]longν=(long)(((buffer[index++]&0xff)<<56)0737]((buffer[index++]&0xff)<<48)0738]I((buffer[index++]&0xff)<<40)0739]I((buffer[index++]&0xff)<<32)0740]I((buffer[index++]&0xff)<<24)0741]((buffer[index++]&0xff)<<16)0742]I((buffer[index++]&0xff)<<8)0743](buffer[index++]&0xff));0744]field.setLong(null,ν);0745]}elseif(type==Double.TYPE){0746]longν=(long)(((buffer[index++]&0xff)<<56)0747]I((buffer[index++]&0xff)<<48)0748]I((buffer[index++]&0xff)<<40)0749]I((buffer[index++]&0xff)<<32)0750]I((buffer[index++]&0xff)<<24)0751]((buffer[index++]&0xff)<<16)0752]I((buffer[index++]&0xff)<<8)0753]I(buffer[index++]&0xff));0754]field.setDouble(null,Double.IongBitsToDouble(v));0755]}else{//Unsupportedfieldtype.0756]thrownewAssertionError("Unsupportedtype.");0757]}0758]}0759]}0760]}0761]}catch(Exceptione){0762]thrownewAssertionError("Exception:"+e.toString());0763]}0764]}0765]}0766]All.FieldLoader.java0767]该摘录是FieldLoader的源代码,其在加载应用时对其进行修改。0768]importjava.lang.~k;importjava.io.*;importjava.net.*;publicclassFieldLoaderextendsURLClassLoader{publicFieldLoader(URL[Juris){super(urls);}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;try{BufferedInputStreamin=newBufferedInputStream(findResource{name,replace('.','/').concat(“.class“)).openStreamO);cf=newClassFile(in);}catch(Exceptione){thrownewClassNotFoundException(e.toStringO);}//Class-widepointerstotheIdcandalertindex.intldcindex=_1;intalertindex=_1;for(inti=O;i<cf.methods_count;i++){for(intj=O;j<cf.methods[i].attributes_count;j++){.if(!(cf.methods[i].attributes[j]instanceofCode_attribute))continue;Code_attributeca=(Code_attribute)cf.methods[i].attributes[j];booleanchanged=false;for(intζ=O;z<ca.code,length;z++){if((ca.code[z]&0xff)==179){//OpcodeforaPUTSTATIC//instruction.changed=true;//Thecodebelowonlysupportsfieldsinthisclass.//Thus,firstoff,checkthatthisfieldislocaltothis//class.CONSTANT—Fieldref—infofi=(CONSTANT—Fieldref—info)cf.constant—pool[(int)(((ca.code[z][l]&0xff)41<<8)(ca.code[ζ][2]&0xff))];CONSTANT_Class_infoci=(CONSTANT_Class_info)cf.constant_pool[fi.class_index];StringcIassName=cf.constant_pool[ci.name_index].toString();if(!name,equals(className)){thrownewAssertionError("Thiscodeonlysupportsfields""localtothisclass");}//0k,nowsearchforthefieldsnameandindex.intindex=O;CONSTANT_NameAndType_infoni=(CONSTANT_NameAndType_info)cf.constant_pool[fi.name_and_type_index];StringfieldName=cf.constant_pool[ni.name_index].toString();for(inta=O;a<cf.fields_count;a++){Stringfn=cf.constant_pool{cf.fields[a].name_index].toString();if(fieldName.equals(fn)){index=a;break;}}//Next,realignthecodearray,makingroomforthe//insertions.byte口[]code2=newbyte[ca.code,length+3][];System,arraycopy(ca.code,0,code2,0,z+1);System,arraycopy(ca.code,z+1,code2,z+4,ca.code,length-(z+1));ca.code=code2;//Next,inserttheLDC_ffinstruction.if(ldcindex==-1){C0NSTANT_String_infocsi=newC0NSTANT_String_info(ci.name_index);cp_info[]cpi=newcp_info[cf.constant_pool.length+1];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cpi[cpi.length-1]=csi;Idcindex=cpi.Iength-I;cf.constant_pool=cpi;cf.constant_pool_count++;}ca.code[z+l]=newbyte[3];ca.code[z+1]=(byte)19;ca.code[z+1][1]=(byte)((ldcindex>>8)&0xff);ca.code[z+1][2]=(byte)(ldcindex&Oxff);//Next,inserttheSIPUSHinstruction.ca.code[z+2]=newbyte[3];ca.code[z+2]=(byte)17;ca.code[z+2][1]=(byte)((index>>8)&0xff);ca.code[z+2][2]=(byte)(index&Oxff);//Finally,insertthe.INV0KESTATICinstruction.if(alertindex==-1){//Thisisthefirsttimethisclassisencourteringtheul;(cl;ul;I)V");43//alertinstruction,sohavetoaddittotheconstant//pool.cp_info[]cpi=newcp_info[cf.constant_pool.length+6];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cf.constant_pool=cpi;cf.constant_pool_count+=6;C0NSTANT_Utf8_infoul=newC0NSTANT_Utf8_info("FieldAlert");cf.constant_pool[cf.constant_pool.length-6]=C0NSTANT_Class_infocl=newC0NSTANT_Class_infocf.constant_pool_count_6);cf.constant_pool[cf.constant_pool.length-5]=ul=newC0NSTANT_Utf8_info("alert");cf.constant_pool[cf.constant_pool.length-4]=ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;cf.constant_pool[cf.constant_pool.length-3]=ul;CONSTANT_NameAndType_infonl=newCONSTANT_NameAndType_info{cf.constant_pool.length-4,cf.constant_pool.Iength-3);cf.constant_pool[cf.constant_pool.length-2]=nl;CONSTANT_Methodref_infoml=newCONSTANT_Methodref_info{cf.constant_pool.length-5,cf.constant_pool.Iength-2);cf.constant_pool[cf.constant_pool.length-1]=ml;alertindex=cf.constant_pool.length-1;}ca.code[z+3]=newbyte[3];ca.code[z+3]=(byte)184;ca.code[z+3][1]=(byte)((alertindex>>8)&0xff);ca.code[z+3][2]=(byte)(alertindex&Oxff);//Andlastly,increasetheCODE_LENGTHandATTRIBUTE_LENGTH//values.ca.code_length+=9;ca.attribute_length+=9;}}//Ifwechangedthismethod,thenincreasethestacksizebyone.if(changed){ca.max_stack++;//Justtomakesure.}}}try{ByteArrayOutputStreamout=newByteArrayOutputStream();44cf.serialize(out);byte[]b=out.toByteArray();returndefineClass(name,b,0,b·length);}catch(Exceptione){thrownewClassNotFoundException(name);}}}fields"A12.Attribute—info,javafields"用于表示ClassFile内的attribute—info结构的Convience类。importjava.lang.*;importjava.io.*;/**Thisabstractclassrepresentsalltypesofattribute_info女thatareusedintheJVMspecifications.±*Allnewattribute_infosubclassesaretoalwaysinheritfromthis*class.*/publicabstractclassattributeinfo{publicintattributenameindex;publicintattribute_length;/**Thisisusedbysubclassestoregisterthemselves*totheirparentclassFile.*/attribute—info(ClassFilecf){}/女女UsedduringinputserializationbyClassFileonly.女/attribute_info(ClassFilecf,DataInputStreamin)throwsIOException{attributenameindex=in.readChar();attribute—length=in.readlnt();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{out.writeChar(attribute—name_index);out.writelnt(attributelength);}/**Thisclassrepresentsanunknownattribute_infothat45*thiscurrentversionofclassfilespecificationdoes*notunderstand.女/publicfinalstaticclassUnknownextendsattribute_info{byte[]info;/**UsedduringinputserializationbyClassFileonly.*/Unknown(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);info=newbyte[attributelength];in.read(info,0,attribute_lemgth);ι/**usedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{ByteArrayOutputStreambaos=newByteArrayOutputStream();super,serialize(out);out.write(info,0,attribute_length);ιιιA13.ClassFile.java用于表示ClassFile结构的Convience类。importjava.lang.~k;importjava.io.~k;importjava.util.;/**TheClassFilefollowsverbatimfromtheJVMspecification.*/publicfinalclassClassFile{publicintmagic;publicintminor_version;publicintmajor_version;publicintconstant_pool_count;publiccp_infο[]constant_pool;publicintaccess—flags;publicintthis_class;publicintsuper_class;publicintinterfaces_count;publicint[]interfaces;publicintfieldscount;757677787980818283publicfield_info[]fields;publicintmethods_count;publicmethod_info[]methods;publicintattributes_count;publicattribute—info[]attributes;/~k-kConstructor.Takesinabytestreamrepresentationandtransforms*eachoftheattributesintheClassFileintoobjectstoallowfor*easiermanipulation.女/publicClassFile(InputStreamins)throwsIOException{DataInputStreamin=(insinstanceofDataInputStream?(DataInputStream)ins:newDataInputStream(ins));magic=in.readlnt();minor_version=in.readChar();[1000]major_version=in.readChar();[1001]constant—pool_count=in.readChar();[1002]constant—pool=newcp_info[constant—pool_count];[1003]for(inti=1;i<constant—pool_count;i++){[1004]in.mark(l);[1005]ints=in.read();[1006]in.reset();[1007]switch(s){[1008]case1:[1009]constant一pool[i]=newCONSTANT一Utf8—info(this,in);[1010]break;[1011]case3:[1012]constant—pool[i]=newC0NSTANT_Integer_info(this,in);[1013]break;[1014]case4:[1015]constant—pool[i]=newCONSTANT—Float_infο(this,in);[1016]break;[1017]case5:[1018]constant—pool[i]=newC0NSTANT_Long—info(this,47in);i++;break;case6:constant一pool[i]=newCONSTANT_Double_info(this,in);i++;break;case7:constant一pool[i]=newC0NSTANT_Class_info(this,in);break;case8:constant一pool[i]=newC0NSTANT_String_info(this,in);break;case9:constant一pool[i]=newCONSTANT一Fieldref一info(this,in);break;case10:constant一pool[i]=newCONSTANT一Methodref一info(this,in);break;case11:constant_pool[i]=newCONSTANT_InterfaceMethodref_info(this,in);break;case12:constant一pool[i]=newCONSTANT_NameAndType_info(this,in);break;default:thrownewClassFormatError("InvalidConstantpoolTag");}}access—flags=in.readChar();this_class=in.readChar();super_class=in.readChar();interfaces_count=in.readChar();interfaces=newint[interfaces_count];for(inti=0;i<interfaces_count;i++)interfaces[i]=in.readChar();fields_count=in.readChar();fields=newfield—info{fieldscount];for(inti=0;i<fields_count;i++){fields[i]=newfield—info(this,in);ιmethods_count=in.readChar();methods=newmethod—info[methods_count];for(inti=0;i<methods_count;i++){methods[i]=newmethod—info(this,in);ιattributes_count=in.readChar();attributes=newattribute_info.[attributescount];for(inti=0;i<attributes_count;i++){in.mark(2);Strings=constant—pool[in.readChar()].toString()in.reset();if(s.equals('SourceFile"))attributes[i]=newSourceFile_attribute(this,in)elseif(s.equals{“Deprecated"))attributes[i]=newDeprecated—attribute(this,in)elseif(s.equals{“InnerClasses“))attributes[i]=newInnerClasses_attribute(this,in)elseattributes[i]=newattribute_info.Unknown(this,in)/**SerializestheClassFileobjectintoabytestream.*publicvoidserialize(OutputStreamo)throwsIOException{DataOutputStreamout=(oinstanceofDataOutputStream?(DataOutputStream)ο:newDataOutputStream(o));out.writelnt(magic);out.writeChar(minor_version);out.writeChar(major_version);out.writeChar(constant—pool—count);491091]1092]1093]1094]1095]1096]1097]1098]1099]1100]1101]1102]1103]1104]1105]1106]1107]1108]1109]1110]1111]1112]1113]1114]1115]1116]1117]1118]1119]1120]1121]1122]1123]1124]1125]1126]1127]1128]1129]for(inti=1;i<constant_pool_count;i++){constant—pool[i]·serialize(out);if(constant_pool[i]instanceofC0NSTANT_Long_info||constant_pool[i]instanceofC0NSTANT_Doub1e_info)i++;}out.writeChar(access_flags);out.writeChar(this_class);out.writeChar(super_class);out.writeChar(interfaces—count);for(inti=0;i<interfaces_count;i++)out.writeChar(interfaces[i]);out.writeChar(fields_count);for(inti=0;i<fields_count;i++)fields[i]·serialize(out);out:writeChar(methods_count);for(inti=0;i<methods_count;i++)methods[i].serialize(out);out.writeChar(attributes—count);for(inti=0;i<attributes_count;i++)attributes[i].serialize(out);//Flushtheoutputstreamjusttomakesure,out.flush0;A14.Code—attribute,java用于表示ClassFile内的Code—attribute结构的Convience类。importjava.util.女;importjava.lang.^;importjava.io.*;/±±女Thecode[]isstoredasa2Darray.女/publicfinalclassCode_attributeextendsattribute_info{publicintmax_stack;publicint_max_locals;publicintcode—length;publicbyte[][]code;publicintexception—table—length;publicexception—table[]exception—table;50[1130]publicintattributes_count;publicattribute_info[]attributes;/女女Internalclassthathandlestheexceptiontable.女/publicfinalstaticclassexception—table{publicintstsrt—pc;publicintend—pc;publicinthandler—pc;publicintcatch—type;}/**Constructorcalledonlybymethod—info·*/Code_attribute(ClassFilecf,intani,intal,intms,intml,intcl,byte[][]cd,intetl,exception_table[]et,intac,attribute—info[]a){super(cf);attribute—name_index=ani;attribute—length=al;max—stack=ms;max_locals=ml;code—length=cl;code_=cd;exception—table—length=etl;exception—table=et;attributes_count=ac;attributes=a;}/女女UsedduringinputserializationbyClassFileonly.女/Code_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);max_stack=in.readChar();max_locals=in.readChar();code—length=in.readlnt();code=newbyte[code_length][];inti=0;for(intpos=0;pos<code—length;i++){in.mark(l);ints=in.read();in.reset();switch(s){51[1169]case16:case18:case21:case22:case23:case24:case25:case54:case55:case56:case57:case58:case169:case188:case196:code[i]=newbyte[2];break;case17:case19:case20:case132:case153:case154:case155:case156:case157:case158:case159:case160:case161:case162:case163:case164:case165:case166:case167:case168:case178:case179:52[1208]case180:case181:case182:case183:case184:case187:case189:case192:case193:case198:case199:case209:code[i]=newbyte[3];break;case197:code[i]=newbyte[4];break;case185:case200:case201:code[i]=newbyte[5];break;case170:{intpad=3_(pos%4);in.mark(pad+13);//highbytein.skipBytes(pad+5);//lowbyteintlow=in.readlnt();code[i]=newbyte[pad+13+((in.readlnt()-low+1)*4)];in.reset();break;}case171:{intpad=3-(pos%4);in.mark(pad+9);in.skipBytes(pad+5);code[i]=newbyte[pad+9+(in.readlnt()*8)];in.reset();break;}default:[1247[1248[1249[1250[1251[1252[1253[1254[1255[1256[1257[1258[1259[1260[1261[1262[1263[1264[1265[1266[1267[1268[1269[1270[1271[1272[1273[1274[1275[1276[1277[1278[1279[1280[1281[1282[1283[1284[1285code[i]=newbyte[1];in.read(code[i],0,code[i].length);pos+=code[i].length;//adjustthearraytothenewsizeandstorethesizebyte[][]temp=newbyte[i][];System,arraycopy(code,0,temp,0,i);code=temp;exception—table—length=in.readChar();exception_tabIe=newCode_attribute.exception_tabIe[exception_table_length]for(i=0;i<exception_table_length;i++){exception_table[i]=newexception_tabIe();exception—table[i]·start_pc=in.readChar();exception_table[i].end_Pc=in.readChar();exception_table[i].handler_pc=in.readChar();exception—table[i]·catch—type=in.readChar();}attributescount=in.readChar();attributes=newattributeinfo[attributescount];for(i=0;i<attributescount;i++){in.mark(2);Strings=cf.constant—pool[in.readChar()].toString();in.reset();if(s.equals(〃LineNumberTable〃))attributes[i]=newLineNumberTableattribute(cf,in);elseif(s.equals{“LocalVariableTable/r))attributes[i]=newLocalVariableTableattribute(cf,in)elseattributes[i]=newattributeinfo.Unknown(cf,in)/**UsedduringoutputserializationbyClassFileonly.女/voidserialize(DataOutputStreamout)throwsIOException{attribute—length=12+code—length+(exception—table—length*8);1286]for(inti=0;i<attributes_count;i++)1287]attribute—length+=attributes[i].attribute—length+61288]super,serialize(out);1289]out.writeChar(max_stack);1290]out.writeChar(max_locals);1291]out.writelnt(code_length);1292]for(inti=0,pos=0;pos<code—length;i++){1293]out.write(code[i],0,code[i].length);1294]pos+=code[i].length;1295]}1296]out.writeChar(exception—table—length);1297]for(inti=0;i<exception—table—length;i++){1298]out.writeChar(exception—table[i]·start—pc);1299]out.writeChar(exception—table[i]·end—pc);1300]out.writeChar(exception—table[i].handler—pc);1301]out.writeChar(exception—table[i]·catch—type);1302]ι1303]out.writeChar(attributes_count);1304]for(inti=0;i<attributes_count;i++)1305]attributes[i].serialize(out);1306]}1307]}1308]A15.CONSTANT—Class—info,java1309]用于表示ClassFile内的C0NSTANT_Class—info结构的Convience类。1310]importjava.lang.*;1311]importjava.io.女;1312]1313]/女女Classsubtypeofaconstantpoolentry.女/1314]publicfina:_classCONSTANT_Class_infoextendscp_info{1315]/**Theindextothenameofthisclass.*/1316]publicintname_index=0;1317]/**Convenienceconstructor.1318]女/1319]publicC0NSTANT_Class_info(intindex){1320]tag=7;1321]name_index=index;1322]}1323]/**UsedduringinputserializationbyClassFileonly.*1324]C0NSTANT_Class_info(ClassFilecf,DataInputStreamin)551325]1326]1327]1328]1329]1330]1331]1332]1333]1334]1335]1336]throwsIOException{super(cf,in);if(tag!=7)thrownewClassFormatError();name_index=in.readChar();/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{out.writeByte(tag);out.writeChar(name_index);1337]}1338]A16.CONSTANTDouble_info.java1339]用于表示ClassFile内的CONSTANTDoubleinfo结构的Convience类。1340]importjava.lang.~k;1341]importjava.io.*;1342]/-k-kDoublesubtypeofaconstantpoolentry.~k/1343]publicfinalclassCONSTANT_Doub1e_infοextendscp_info{1344]/-A--A-Theactualvalue./1345]publicdoublebytes;1346]publicCONSTANT_Double_info(doubled){1347]tag=6;1348]bytes=d;1349]}1350]/-k-kUsedduringinputserializationbyClassFileonly.~k/1351]CONSTANT_Double_info(ClassFilecf,DataInputStreamin)1352]throwsIOException{1353]super{cf,in);1354]if(tag!=6)1355]thrownewClassFormatError(};1356]bytes=in.readDouble();1357]}1358]/**UsedduringoutputserializationbyClassFileonly.*/1359]voidserialize{DataOutputStreamout)1360]throwsIOException{1361]out.writeByte(tag);1362]out.writeDouble(bytes);1363]long1=Double.doubleToLongBits(bytes);56[1364]}}A17.CONSTANT—Fieldref—info,java用于表示ClassFile内的CONSTANT—Fieldref—info结构的Convience类。importjava.lang.*;importjava.io.*;/**Fieldrefsubtypeofaconstantpoolentry.*/publicfinalclassCONSTANT—Fieldref—infoextendscp_info{/**Theindextotheclassthatthisfieldisreferencingto.*publicintclass_index;/**Thenameandtypeindexthisfieldifreferencingto.*/publicintname_and_type_index;/**Convenienceconstructor.*/publicCONSTANT—Fieldref—info(intclass_index,intname_and—type—index){tag=9;this.class_index=class_index;this.name_and_type_index=name_and_type_index;}/女女UsedduringinputserializationbyClassFileonly.女/C0NSTANT_Fieldref_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=9)thrownewClassFormatError();class_index=in.readChar();name_and_type_index=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException[out.writeByte(tag);out.writeChar(class_index);out.writeChar(name_and_type_index);}}A18.CONSTANT—Float—info,java57[1401]用于表示ClassFile内的CONSTANT_Float_info结构的Convience类。importjava.lang.~k;importjava.io.~k;/**Floatsubtypeofaconstantpoolentry.*/publicfinalclassC0NSTANT_Float_infoextendscp_info{/**Theactualvalue.*/publicfloatbytes;publicC0NSTANT_Float_info(floatf){tag=4;bytes=f;}/-k-kUsedduringinputserializationbyClassFileonly.*/C0NSTANT_Float_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=4)thrownewClassFormatError();bytes=in.readFloat();}/**UsedduringoutputserializationbyClassFileonly.*/publicvoidserialize(DataOutputStreamout)throwsIOException{out.writeByte(4);out.writeFloat(bytes);}}A19.C0NSTANT_Integer_info.java用于表示ClassFile内的C0NSTANT_Integer—info结构的Convience类。importjava.lang.~k;importjava.io.~k;/-A--A-Integersubtypeofaconstantpoolentry.~k/publicfinalclassC0NSTANT_Integer_infoextendscp_info{/**Theactualvalue.*/publicintbytes;publicC0NSTANT_Integer_info(intb){tag=3;bytes=b;}/**UsedduringinputserializationbyClassFileonly.*/1440]CONSTANT_Integer_info(ClassFilecf,DataInputStreamin)1441]throwsIOException{1442]super(cf,in);1443]if(tag!=3)1444]thrownewClassFormatError();1445]bytes=in.readlnt();1446]}1447]/**UsedduringoutputserializationbyClassFileonly.*/1448]publicvoidserialize(DataOutputStreamout)1449]throwsIOException{1450]out.writeByte(tag);1451]out.writelnt(bytes);1452]}}A20.CONSTANT_InterfaceMethodref_info.java用于表示ClassFiIe内的CONSTANT—InterfaceMethodref_infο结构的Convience类。importjava.lang.女;importjava.io.*;I±±InterfaceMethodrefsubtypeofaconstantpoolentry.1459]*/1460]publicfinalclassCONSTANT_InterfaceMethodref_infoextendscp_info{1461]I±±Theindextotheclassthatthisfieldisreferencingto.女/1462]publicintclass_index;1463]/**Thenameandtypeindexthisfieldifreferencingto.*/1464]publicintname_and_type_index;1465]publicCONSTANT_InterfaceMethodref_info(intclass_index,1466]intname_and_type_index)1467]tag=11;1468]this.class_index=class_index;1469]this.name_and_type_index=name_and_type_index;1470]}1471]/**UsedduringinputserializationbyClassFileonly.*/1472]CONSTANT_InterfaceMethodref_info(ClassFilecf,DataInputStreamin)1473]throwsIOException{1474]super(cf,in);1475]if(tag!=11)1476]thrownewClassFormatError();591477]class—index=in.readChar();1478]name_and_type_index=in.readChar();1479]}1480]/**UsedduringoutputserializationbyClassFileonly.*/1481]voidserialize(DataOutputStreamout)1482]throwsIOException{1483]out.writeByte(tag);1484]out.writeChar(class_index);1485]out.writeChar(name_and_type_index);1486]}1487]}1488]A21.CONSTANT—Long—info,java1489]用于表示ClassFile内的CONSTANT—Long—info结构的Convience类。1490]importjava.lang.女;1491]importjava.io.*;1492]/女女Longsubtypeofaconstantpoolentry.女/1493]publicfinalclassC0NSTANT_Long—infoextendscp_info{1494]/女女Theactualvalue.女/1495]publiclongbytes;1496]publicC0NSTANT_Long_info(longb){1497]tag=5;1498]bytes=b;1499]}1500]/**UsedduringinputserializationbyClassFileonly.*/1501]C0NSTANT_Long_info(ClassFilecf,DataInputStreamin)1502]throwsIOException{1503]super(cf,in);1504]if(tag!=5)1505]thrownewClassFormatError();1506]bytes=in.readLong();1507]}1508]/**UsedduringoutputserializationbyClassFileonly.*/1509]voidserialize(DataOutputStreamout)1510]throwsIOException{1511]out.writeByte(tag);1512]out.writeLong(bytes);1513]}1514]}1515]A22.CONSTANT_Methodref_info.java60[1516]用于表示ClassFile内的CONSTANT—Methodref—info结构的Convience类。importjava.lang.*;importjava.io.*;/女女Methodrefsubtypeofaconstantpoolentry.*/publicfinalclassCONSTANT—Methodref—infoextendscp_info{/女女Theindextotheclassthatthisfieldisreferencingto.女/publicintclass_index;/**Thenameandtypeindexthisfieldifreferencingto.*/publicintname_and_type_index;publicCONSTANT—Methodref—info(intclass_index,intname—and—type_index){tag=10;this.class_index=class_index;this.name_and_type_index=name_and_type_index;}/女女UsedduringinputserializationbyClassFileonly.女/C0NSTANT_Methodref_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=10)thrownewClassFormatError();class_index=in.readChar();name_and_type_index=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{out.writeByte(tag);out.writeChar(class_index);out.writeChar(name_and_type_index);}1548]}1549]A23.CONSTANT—NameAndType_infο·java1550]用于表示ClassFile内的CONSTANT—NameAndType—info结构的Convience类。1551]importjava.io.*;1552]importjava.lang.*;[1553]/**NameAndTypesubtypeofaconstantpoolentry.[1554]女/[1555]publicfinalclassCONSTANT—NameAndType_infoextendscp_info{[1556]/**TheindextotheUtf8thatcontainsthename.*/[1557]publicintname_index;[1558]/**TheindexfotheUtf8thatconstainsthesignature.女/[1559]publicintdescriptor—index;[1560]publicCONSTANT—NameAndType_info(intname_index,intdescriptor—index}{[1561]tag=12;[1562]this.name_index=name_index;[1563]this,descriptor—index=descriptor—index;[1564]ι[1565]/**UsedduringinputserializationbyClassFileonly.*/[1566]CONSTANT—NameAndType_info(ClassFilecf,DataInputStreamin)[1567]throwsIOException{[1568]super(cf,in);[1569]if(tag!=12)[1570]thrownewClassFormatError();[1571]name—index=in.readChar();[1572]descriptor_index=in.readChar();[1573]ι[1574]/**UsedduringoutputserializationbyClassFileonly.女/[1575]voidserialize(DataOutputStreamout)[1576]throwsIOException{[1577]out.writeByte(tag);[1578]out.writeChar(name_index);[1579]out.writeChar(descriptor—index);[1580]ι[1581]ι[1582]A24.CONSTANT_String_info.java[1583]用于表示ClassFile内的CONSTANT_String_info结构的Convience类ο[1584]importjava.lang.~k;[1585]importjava.io.~k;[1586]/-k-kStringsubtypeofaconstantpoolentry.[1587]女/[1588]publicfinalclassCONSTANT_String—infoextendscp_info{[1589]/女女Theindextotheactualvalueofthestring.女/[1590]publicintstring—index;1591]publicCONSTANT_String_info(intvalue){1592]tag=8;1593]string—index=value;1594]}1595]I±±ONLYTOBEUSEDBYCLASSFILE!±/1596]publicCONSTANT_String—info(ClassFilecf,DataInputStreamin)1597]throwsIOException{1598]super(cf,in);1599]if(tag!=8)1600]thrownewClassFormatError();1601]string—index=in.readChar();1602]}1603]/**Outputserialization,ONLYTOBEUSEDBYCLASSFILE!*/1604]publicvoidserialize(DataOutputStreamout)1605]throwsIOException{1606]out.writeByte(tag);1607]out.writeChar(string—index);1608]}1609]}1610]A25.CONSTANT—Utf8—info,java1611]用于表示ClassFile内的CONSTANT—Utf8—info结构的Convience类。1612]importjava.io.*;1613]importjava.lang.*;1614]/**Utf8subtypeofaconstantpoolentry.1615]*WeinternallyrepresenttheUtf8infobytearray1616]asaString.1617]±/1618]publicfinalclassC0NSTANT_Utf8_infoextendscp_info{1619]/±±Lengthofthebytearray.女/1620]publicintlength;1621]/±±Theactualbytes,representedbyaString.女/1622]publicStringbytes;1623]/**Thisconstructorshouldbeusedforthepurpose1624]*ofpartcreation.Itdoesnotsettheparent1625]*ClassFilereference.1626]*/1627]publicCONSTANT—Utf8—info(Strings){1628]tag=1;1629]length=s.length();63[1630]bytes=s;}/女女UsedduringinputserializationbyClassFileonly.女/publicC0NSTANT_Utf8_info(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);if(tag!=1)thrownewClassFormatError();length=in.readChar();byte[]b=newbyte[length];in.read(b,O,length);//WARNING:Stringconstructorisdeprecated.bytes=newString(b,0,length);}/**UsedduringoutputserializationbyClassFileonly.*/publicvoidserialize(OataOutputStreamout)throwsIOException{out.writeByte(tag);out.writeChar(length);//WARNING:HandlingofStringcoversionheremightbeproblematic.out.writeBytes(bytes);}publicStringtoString(){returnbytes;}}A26.ConstantValue_attribute.javaflgT^^ClassFile内白勺ConstantValue_attribute@丰勾白勺Convience#。importjava.lang.*;importjava.io.*;/**Attributethatallowsforinitializationofstaticvariablesin*classes.Thisattributewillonlyresideinafieldinfo_struct.*/publicfinalclassConstantValue_attributeextendsattribute_info{publicintconstantvalue_index;publicConstantValue_attribute(ClassFilecf,intani,intal,intcvi){super(cf);64[1667]attribute—name_index=ani;attribute—length=al;constantvalue_index=cvi;}publicConstantValue_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);constantvalue_index=in.readChar();}publicvoidserialize(DataOutputStreamout)throwsIOException{attribute_length=2;super,serialize(out);out.writeChar(constantvalue—index);}[1682]}A27.cp_info.java用于表示ClassFile内的cp—info结构的Convience类。importjava.lang.*;importjava.io.*;/**Representsthecommoninterfaceofallconstantpoolparts*thatallspecificconstantpoolitemsmustinheritfrom.±*/publicabstractclasscp_info{/女女Thetypetagthatsignifieswhatkindofconstantpool*itemitis*/publicinttag;/**Usedforserializationoftheobjectbackintoabytestream.女/abstractvoidserialize(DataOutputStreamout)throwsIOException;/**Defaultconstructor.Simplydoesnothing.*/publiccp—info(){}/**ConstructorsimplytakesintheClassFileasareferenceto*it'sparent*/publiccp_info(ClassFilecf){}/女女UsedduringinputserializationbyClassFileonly.女/651704]cp_info(ClassFilecf,DataInputStreamin)1705]throwsIOException{1706]tag=in.readUnsignedByte();1707]}}A28.Deprecated—attribute·javaflgT^^ClassFile白勺Deprecated一attribute@丰勾白勺Convience#。importjava.lang.*;importjava.io.*;/**AfixattributedthatcanbelocatedeitherintheClassFile,1714]*field—infoorthemethod—infoattribute.Markdeprecatedto1715]*indicatethatthemethod,classorfieldhasbeensuperceded.1716]±/1717]publicfinalclassDeprecated—attributeextendsattribute_info{1718]publicDeprecated—attribute(ClassFilecf,intani,intal){1719]super(cf);1720]attribute—name_index=ani;1721]attribute_length=al;1722]}1723]/±±UsedduringinputserializationbyClassFileonly.女/1724]Deprecated—attribute(ClassFilecf,DataInputStreamin)1725]throwsIOException{1726]super(cf,in);1727]}1728]}1729]A29.ExCeptions_attribute.java1730]flgT^^ClassFile白勺Exceptions—attribute@丰勾白勺Convience#。1731]importjava.lang.*;1732]importjava.io.*;1733]/**Thisisthestructwheretheexceptionstablearelocated.1734]±<br><br>1735]±Thisattributecanonlyappearonceinamethod—infostruct.1736]*/1737]publicfinalclassExceptions_attributeextendsattribute_info{1738]publicintnumber_of—exceptions;1739]publicint[]exception—index—table;1740]publicExceptions_attribute(ClassFilecf,intani,intal,intnoe,1741]int[]eit){1742]super(cf);[1743]attribute—name_index=ani;attribute_length=al;number_of—exceptions=noe;exception—index—table=eit;}/女女UsedduringinputserializationbyClassFileonly.女/Exceptions_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);number_of—exceptions=in.readChar();exception_index_table=newint[numberofexceptions];for(inti=0;i<number_of—exceptions;i++)exception_index_table[i]=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/publicvoidserialize(DataOutputStreamout)throwsIOException{attribute_length=2+(number_of—exceptions*2);super,serialize(out);out.writeChar(number_of—exceptions);for(inti=0;i<number_of—exceptions;i++)out.writeChar(exception—index—table[i]);}}A30.field—info,java用于表示ClassFile内的field—info结构的Convience类。importjava.lang.*;importjava.io.*;1771]/**Representsthefield—infostructureasspecifiedintheJVM1772]specification.1773]*/1774]publicfinalclassfield—info{1775]publicintaccess_flags;1776]publicintname_index;1777]publicintdescriptor—index;1778]publicintattributes_count;1779]publicattribute_info[]attributes;1780]/**Convenienceconstructor.*/1781]publicfield—info(ClassFilecf,intflags,intni,intdi){6717821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819access_flags=flags;nameindex=ni;descriptor_index=di;attributes_count=0;attributes=newattribute_info;}/女女Constructorcalledonlyduringtheserializationprocess.*<br><br>*Thisisintentionallyleftaspackageprotectedaswe*shouldnotnormallycallthisconstructordirectly.*<br><br>Warning:thehandlingofIenisnotcorrect(afterStrings女/field—info(ClassFilecf,DataInputStreamin)throwsIOException{access_flags=in.readChar();name—index=in.readChar();descriptor_index=in.readChar();attributes_count=in.readChar();attributes=newattribute_info[attributes_count];for(inti=0;i<attributes_count;i++){in.mark(2);Strings=cf.constant—pool[in.readChar()].toString();in.reset();if(s.equals(〃ConstantValue〃))attributes[i]=newConstantValue_attribute(cf,in);elseif(s.equals{“Synthetic"))attributes[i]=newSynthetic_attribute(cf,in);elseif(s.equals{“Deprecated/r))attributes[i]=newDeprecated—attribute(cf,in);elseattributes[i]=newattribute_info.Unknown(cf,in);/**Toserializethecontentsintotheoutputformat.女/publicvoidserialize(DataOutputStreamout)throwsIOException{68[1820]out.writeChar(access_flags);out.writeChar(name_index);out.writeChar(descriptor—index);out.writeChar(attributes_count);for(inti=0;i<attributes_count;i++)attributes[i].serialize(out);}}A31.InnerClasses_attribute.javaflgT^^ClassFile内白勺InnerClasses_attribute@丰勾白勺Convience#。importjava.lang.*;importjava.io.*;/**Avariablelengthstructurethatcontainsinformationaboutan*innerclassofthisclass.*/publicfinalclassInnerClasses_attributeextendsattribute_info{publicintnumber_of—classes;publicclasses[]classes;publicfinalstaticclassclasses{intinner_class_info_index;intouter_class_info_index;intinner—name_index;intinner_class_access_flags;}publicInnerClasses_attribute(ClassFilecf,intani,intal,intnoc,classes[]c){super(cf);attribute—name_index=ani;attribute_length=al;number_of—classes=noc;classes=c;}/女女UsedduringinputserializationbyClassFileonly.女/InnerClasses_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);number_of—classes=in.readChar();classes=newInnerClasses_attribute,classes[number_ofclasses];69[1858]for(inti=0;i<number_of—classes;i++){[1859]classes[i]=newclasses();[1860]classes[i].inner_class_info_index=in.readChar();[1861]classes[i].outer_class_info_index=in.readChar();[1862]classes[i].inner—name_index=in.readChar();[1863]classes[i].inner_class_access_flags=in.readChar();[1864]ι[1865]ι[1866]/**UsedduringoutputserializationbyClassFileonly.*/[1867]publicvoidserialize(DataOutputStreamout}[1868]throwsIOException{[1869]attribute_length=2+(number_of—classes*8);[1870]super.serialize(out);[1871]out.writeChar(number_of—classes);[1872]for(inti=0;i<number_of—classes;i++){[1873]out.writeChar(classes[i].inner_class_info_index);[1874]out.writeChar(classes[i].outer_class_info_index);[1875]out.writeChar(classes[i].inner—name_index);[1876]out.writeChar(classes[i].inner_class_access_flags);[1877]ι[1878]ι[1879]}[1880]A32.LineNumberTable_attribute.jaVa[1881]fflT^^ClassFile白勺LineNumberTable_attributeg丰勾白勺Convienceg。[1882]importjava.lang.^;[1883]importjava.io.*;[1884]/女-kDetermineswhichlineofthebinarycoderelatestothe[1885]*correspondingsourcecode.[1886]/[1887]publicfinalclassLineNumberTable_attributeextendsattribute_info{[1888]publicintline—number_table_length;[1889]publicline—number_table[]line—number_table;[1890]publicfinalstaticclassline—number_table{[1891]intstart—pc;[1892]intline—number;[1893]ι[1894]publicLineNumberTable_attribute(ClassFilecf,intani,intal,intIntl,[1895]line—number_table[]Int){[1896]super(cf);attribute—name_index=ani;attribute_length=al;line—number—table—length=Intl;line—number—table=Int;}/女女UsedduringinputserializationbyClassFileonly.女/LineNumberTable_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);line—number_table_length=in.readChar();line—number—table=newLineNumberTable_attribute.1ine_number_table[1ine_number_table_length];for(inti=0;i<line—number—table—length;i++){line—number—table[i]=newline—number_table();line—number_table[i]·start—pc=in.readChar();line—number_table[i]·line—number=in.readChar();}}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{attribute_length=2+(line—number_table_length*4);super,serialize(out);out.writeChar(line—number_table_length);for(inti=0;i<line—number—table—length;i++){out·writeChar(line—number—table[i]·start—pc);out·writeChar(line—number—table[i]·line—number);}}}A33.LocalVariableTable—attribute·javaflgT^^ClassFile白勺LocalVariableTable_attribute@丰勾白勺Convience#。importjava.lang.*;importjava.io.*;/**Usedbydebuggertofindouthowthesourcefilelinenumberislinked女tothebinarycode.Ithasmanytoonecorrespondenceandisfound71ininfo{al,tablet]*theCode_attribute.女/publicfinalclassLocalVariableTable_attributeextendsattribute—publicintlocal_variable_table_length;publiclocal_variable_table[]local_variable_table;publicfinalstaticclasslocal_variable_table{intstart—pc;intlength;intname_index;intdescriptor_index;intindex;ιpublicLocalVariableTable_attribute(ClassFilecf,intani,intintlvtl,localvariablelvt){super(cf);attribute—name_index=ani;attribute_length=al;local—variable—table—length=lvtl;local—variable—table=Ivt;)/**UsedduringinputserializationbyClassFileonly.*/LocalVariableTable_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);local_variable_table_length=in.readChar();local—variable—table=newLoca1VariableTable_attribute.local_variable_table[local_variable_table—length];for(inti=O;i<local—variable—table—length;i++){local—variable—table[i]=newlocal—variable—table();local_variable_table[i].start—pc=in.readChar();local_variable_table[i].length=in.readChar();local_variable_table[i].name_index=in.readChar();72[1967]local—variable—table[i].descriptor—index=in.readChar();local_variable_table[i].index=in.readChar();}}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException(attribute—length=2+(local—variable—table—length女10);super,serialize(out);out.writeChar(local_variable_table_length);for(inti=0;i<local—variable—table—length;i++){out·writeChar(local—variable—table[i]·start—pc);out.writeChar(local_variable_table[i].length);out.writeChar(local_variable_table[i].name_index);out·writeChar(local—variable—table[i]·descriptor—index);out·writeChar(local—variable—table[i]·index);}}}A34.methOd—info,java用于表示ClassFile内的method—info结构的COnvienCe类。importjava.lang.*;importjava.io.*;/**Thisfollowsthemethod—infointheJVMspecification.*/publicfinalclassmethod—info{publicintaccess_flags;publicintname_index;publicintdescriptor—index;publicintattributes_count;publicattribute_info[]attributes;/**Constructor.Createsamethod—info,initializesitwith女theflagsset,andthenameanddescriptorindexesgiven.*Anewuninitializedcodeattributeisalsocreated,andstored*inthe<i>code</invariable.*/publicmethod—info(ClassFilecf,intflags,intni,intdi,intac,attribute_info[la)(access_flags=flags;name_index=ni;[2006]descriptor_index=di;[2007]attributes_count=ac;[2008]attributes=a;[2009]}[2010]/**Thismethodcreatesamethod—infofromthecurrentpointerinthe[2011]女datastream.Onlycalledbyduringtheserializationofacomplete[2012]*ClassFilefromabytestream,notnormallyinvokeddirectly.[2013]女/[2014]method—info(ClassFilecf,DataInputStreamin)[2015]throwsIOException{[2016]access_flags=in.readChar();[2017]name—index=in.readChar();[2018]descriptor_index=in.readChar();[2019]attributes_count=in.readChar();[2020]attributes=newattribute_info[attributes_count];[2021]for(inti=0;i<attributes_count;i++){[2022]in.mark(2);[2023]Strings=cf.constant—pool[in.readChar()].toString();[2024]in.reset();[2025]if(s.equals(,rCode"))[2026]attributes[i]=newCode_attribute(cf,in);[2027]elseif(s.equals{“Exceptions'7))[2028]attributes[i]=newExceptions_attribute(cf,in);[2029]elseif(s.equals{“Synthetie/r))[2030]attributes[i]=newSynthetic_attribute(cf,in);[2031]elseif(s.equals{“Deprecated/r))[2032]attributes[i]=newDeprecated—attribute(cf,in);[2033]else[2034]attributes[i]=newattribute_info.Unknown(cf,in);[2035]ι[2036]ι[2037]/女女Outputserializationofthemethod—infotoabytearray.[2038]*Notnormallyinvokeddirectly.[2039]女/[2040]publicvoidserialize(DataOutputStreamout)[2041]throwsIOException{[2042]out.writeChar(access_flags);74[2044]out.writeChar(descriptor—index);out.writechar(attributes—count);for(inti=0;i<attributes_count;i++)attributes[i].serialize(out);}}A35.SourceFile—attribute·javaffiT^^ClassFile白勺SourceFile_attribute@丰勾白勺Convience#。importjava.lang.*;importjava.io.*;/**ASourceFileattributeisanoptionalfixed—lengthattributein*theattributestable.OnlylocatedintheClassFilestructonly±once.±/publicfinalclassSourceFile_attributeextendsattribute_info{publicintsourcefile—index;publicSourceFile_attribute(ClassFilecf,intani,intal,intsfi){super(cf);attribute—name_index=ani;attribute_length=al;sourcefile—index=sfi;}/±±UsedduringinputserializationbyClassFileonly.女/SourceFile_attribute(ClassFilecf,DataInputStreamin)throwsIOException{super(cf,in);sourcefile—index=in.readChar();}/**UsedduringoutputserializationbyClassFileonly.*/voidserialize(DataOutputStreamout)throwsIOException{attribute_length=2;super,serialize(out);out.writeChar(sourcefile—index);}}A36.Synthetic—attribute·javaflgT^^ClassFile白勺Synthetic—attribute@丰勾白勺Convience#。752082]importjava.lang.~k;2083]importjava.io.~k;2084]/**Asyntheticattributeindicatesthatthisclassdoesnothave2085]*ageneratedcodesource.Itislikelytoimplythatthecode2086]~kisgeneratedbymachinemeansratherthancodeddirectly.This2087]~kattributecanappearintheclassfile,method_infoorfield_info.2088]*Itisfixedlength.2089]女/2090]publicfinalclassSynthetic_attributeextendsattribute_info{2091]publicSynthetic_attribute(ClassFilecf,intani,intal){2092]super(cf);2093]attribute—name_index=ani;2094]attribute_length=al;2095]ι2096]/**UsedduringoutputserializationbyClassFileonly.*/2097]Synthetic_attribute(ClassFilecf,DataInputStreamin)2098]throwsIOException{2099]super(cf,in);2100]}2101]}2102]附件B2103]Bl2104]Method<clinit>2105]0new#2〈Classtest>2106]3dup2107]4invokespecial#3〈Methodtest()>2108]7putstatic#4〈FieldtestthisTest>2109]10return2110]B22111]Method<clinit>2112]0invokestatic#3〈MethodbooleanisAlreadyLoaded()>2113]3ifeq72114]6return2115]7new#5〈Classtest〉2116]10dup2117]11invokespecial#6〈Methodtest()>2118]14putstatic#7〈FieldtestthisTeSt>2119]17return2120]B32121]Method<init>2122]0al0ad_02123]1invokespecial#l<Methodjava.lang.Object()>2124]4aload_02125]5invokestatic#2<MethodlongcurrentTimeMillis()>2126]8putfield#3<Fieldlongtimestamp>2127]11return2128]B42129]Method<init>2130]0aload_02131]1invokespecial#l<Methodjava.lang.Object()>2132]4invokestatic#2<MethodbooleanisAlreadyLoaded()>2133]7ifeq112134]10return2135]11aload_02136]12invokestatic#4<MethodlongcurrentTimeMillis()>2137]15putfield#5<Fieldlongtimestamp>2138]18return2139]B52140]Method<clinit>2141]0ldc#2<String"test")2142]2invokestatic#3<MethodbooleanisAlreadyLoaded(java.lang.String))2143]5ifeq92144]8return2145]9new#5<Classtest)2146]12dup2147]13invokespecial#6<Methodtest()>2148]16putstatic#7<FieldtestthisTest>2149]19return2150]B62151]Method<init>2152]0aload02153]1invokespecial#l<Methodjava.lang.Object()>2154]4aload_02155]5invokestatic#2<MethodbooleanisAlreadyLoaded(java.lang.Object))2156]8ifeq122157]11return2158]12aload_02159]13invokestatic#4<MethodlongcurrentTimeMillis()>7773/105页[2161][2162]port"))[2181][2182],,,16putfield#5<Fieldlongtimestamp>19return附件B7该摘录是InitClient的源代码,其针对相关类或对象的初始化状态来查询"initialisationserver”。importjava.lang.女;importjava.util.女;importjava.net.女;importjava.io.*;publicclassInitClient{/**Protocolspecificvalues.*/CLOSE=-1;NACK=0;ACK=1;INITIALIZE—CLASS=10;INITIALIZE—OBJECT=2o;/**Initservernetworkvalues.*/publicfinalstaticStringserverAddress=System.getProperty(〃InitServer—network—address〃);publicfinalstaticintserverPort=Integer,parselnt(System.getProperty(“InitServer_network_publicfinalstaticintpublicfinalstaticintpublicfinalstaticintpublicfinalstaticintpublicfinalstaticint/女女TableofglobalID/sforlocalobjects.(hashcode-to-globalIDmappings)*/publicfinalstaticHashtablehashCodeToGlobalID=newHashtable();/**Calledwhenaobjectisbeinginitialized.*/publicstaticbooleanisAlreadyLoaded(Objecto){//Firstofall,weneedtoresolvetheglobalID//forobject'ο'.TodothisweusethehashCodeToGlobalID//table.intglobalID=((Integer)hashCodeToGlobalID·get(o)).intValue();try{//Next,wewanttoconnecttothelnitServer,whichwillinformus//oftheinitializationstatusofthisobject.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.getOutputStream());DataInputStreamin=newDataInputStream(socket.getlnputStream());78[2198]//Ok,nowsendtheserializedrequesttothelnitServer.out.writelnt(INITIALIZE—OBJECT);out.writelnt(globalID);out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremoteside//sendssomething.if(status==NACK){thrownewAssertionError(”Negativeacknowledgement.Requestfailed.”);}elseif(status!=ACK){thrownewAssertionError(〃Unknownacknowledgement“+status+".Requestfailed.");}//Next,readina32bitargumentwhichisthecountofprevious//initializations.intcount=in.readlnt();//Ifthecountisequalto0,thenthisisthefirst//initialization,andhenceisAlreadyLoadedshouldbefalse.//Ifhowever,thecountisgreaterthan0,thenthisisalready//initialized,andthusisAlreadyLoadedshouldbetrue.booleanisAlreadyLoaded=(count==Ofalse:true);//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.close();socket,close();//Makesuretoclosethesocket.//ReturnthevalueoftheisAlreadyLoadedvariable.returnisAlreadyLoaded;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}/**Calledwhenaclassisbeinginitialized.*/publicstaticbooleanisAlreadyLoaded(Stringname){try(//Firstofall,wewanttoconnecttothelnitServer,whichwill[2237]//infornusoftheinitializationstatusofthisclass.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.getOutputStream());DataInputStreamin=newDataInputStream(socket.getlnputStream());//0k,nowsendtheserializedrequesttotheInitServer.out.writelnt(INITIALIZE—CLASS);out.writelnt(name,length());//A32bitlengthargumentof//theStringname.out.write(name.getBytes(),0,name,length());//Thebyte-//encoded//Stringname.out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremoteside//sendssomething.if(status==NACK){thrownewAssertionError{”Negativeacknowledgement.Requestfailed.”);)elseif(status!=ACK){thrownewAssertionError(〃Unknownacknowledgement:“+status+".Requestfailed.");}//Next,readina32bitargumentwhichisthecountofthe//previousintializations·intcount=in.readlnt();//Ifthecountisequalto0,thenthisisthefirst//initialization,andhenceisAlreadyLoadedshouldbefalse.//Ifhowever,thecountisgreaterthan0,thenthisisalready//loaded,andthusisAlreadyLoadedshouldbetrue.booleanisAlreadyLoaded=(count==0false:true};//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.closeQ;80[2275]socket,close();//Makesuretoclosethesocket.//ReturnthevalueoftheisAlreadyLoadedvariable.returnisAlreadyLoaded;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}}附件B8该摘录是InitServer的源代码,其接收InitClient的初始化状态查询,并作出响应将对应的状态返回。importjava.lang.*;importjava.util.*;importjava.net.*;importjava.io.*;publicclassInitServerimplementsRunnable{/**Protocolspecificvalues*/publicfinalstaticintCLOSE=-1;[2291]publicfinalstaticintNACK=0;[2292]publicfinalstaticintACK=1;[2293]publicfinalstaticintlNITIALIZE—CLASS=10;[2294]publicfinalstaticintINITIALIZE_0BJECT=20/**InitServernetworkvalues.*/publicfinalstaticintserverPort=20001;/**Tableofinitializationrecords.*/publicfinalstaticHashtableinitializations=newHashtable();/**Privateinput/outputobjects.*/privateSocketsocket=null;privateDataOutputStreamoutputStream;privateDataInputStreaminputStream;privateStringaddress;publicstaticvoidmain(String[]s)throwsException{System,out.println("InitServer—network—address=“+InetAddress.getLocalHost().getHostAddress());System,out.println("InitServer—network—port=“+serverPort);//Createaserversockettoacceptincominginitializationoperation//connections.ServerSocketserverSocket=newServerSocket(serverPort);81[2312]while(!Thread,interrupted()){//Blockuntilanincominginitializationoperationconnection.Socketsocket=serverSocket.accept();//CreateanewinstanceofInitservertomanagethis//initializationoperationconnection.newThread(newInitServer(socket)).start();}}/**Construetor·InitializethisnewlnitServerinstancewithnecessaryresourcesforoperation.*/publicInitServer(Sockets){socket=s;try{outputStream=newDataOutputStream(s.getOutputStream());inputStream=newDataInputStream(s.getlnputStreamO);address=s.getlnetAddress().getHostAddress();}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}/**Maincodebody.Decodeincominginitializationoperationrequestsandexecuteaccordingly.*/publicvoidrun(){try{//Allcommandsareimplementedas32bitintegers.//Legalcommandsarelistedinthe〃protocolspecificvalues"//fieldsabove.intcommand=inputStream.readlnt();//ContinueprocessingcommandsuntilaCLOSEoperation.while(command!=CLOSE){if(command==INITIALIZE—CLASS){//Thisisan//INITIALIZE—CLASS//operation.//Readina32bitlengthfield'1‘,andaStringnamefor//thisclassoflength'Γ·intlength=inputStream.readlnt();82[2348]byte[]b=newbyte[length];inputStream.read(b,0,b.length);StringcIassName=newString(b,0,length);//Synchronizeontheinitializationstableinorderto//ensurethread-safety.synchronized(initializations){//Locatethepreviousinitializationsentryforthis//class,ifany.Integerentry=(Integer)initializations·get(className);if(entry==null){//Thisisanunknownclassso//updatethetablewitha//correspondingentry.initializations,put(className,newlnteger(1));//sendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializations//ofthisclass-whichinthiscaseofanunknown//classmustbe0.outputStream.writelnt(ACK);outputStream.writelnt(0);outputStream.flush();}else(//Thisisaknownclass,soupdate//thecountofinitializations.initializations,put(className,newInteger(entry.intValue()+1));//SendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializtions//ofthisclass-whichinthiscaseofaknownclass//mustbethevalueof〃entry.intValue()〃.outputStream.writelnt(ACK);outputStream.writelnt(entry.intValue());outputStream.flush();}}}elseif(command==INITIALIZE—OBJECT){//Thisisan//INITIALIZEOBJECT//operation.//ReadintheglobalIDoftheobjecttobeinitialized.[2385]intglobalID=inputStream.readlnt();//Synchronizeontheinitializationstableinorderto//ensurethread-safety.synchronized(initializations){//Locatethepreviousinitializationsentryforthis//object,ifany.Integerentry=(Integer)initializations,get(newlnteger(globalID));if(entry==null){//Thisisanunknownobjectso//updatethetablewitha//correspondingentry.initializations,put(newInteger(globalID),newlnteger(1));//SendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializations//ofthisobject—whichinthiscaseofanunknown//objectmustbe0.outputStream.writelnt(ACK);outputStream.writelnt(0);outputStream.flush();}else{//Thisisaknownobjectsoupdatethe//countofinitializations.initializations,put(newlnteger(qloballD},newlnteger(entry.intValue()+1));//SendapositiveacknowledgementtoInitClient,//togetherwiththecountofpreviousinitializations//ofthisobject-whichinthiscaseofaknown//objectmustbevalue"entry.intValue()“.outputStream.writelnt(ACK);outputStream.writelnt(entry.intValue());outputStream.flush();}}}else{//Unknowncommand.thrownewAssertionError(〃Unknowncommand.Operationfailed.〃);}//Readinthenextcommand.command=inputStream.readlnt();84[2424]}}catch(Exceptione){thrownewAssertionError("Exception:"+e.toString());}finally{try{//Closingdown.Cleanupthisconnection.outputStream.flush();outputStream.close();inputStream.close();socket,close();}catch(ThrowabIet){t.printStackTrace();}//Garbagethesereferences.outputStream=null;inputStream=null;socket=null;}}}附件B9该摘录是附件B的示例之前/之后所使用的示例应用的源代码。importjava.lang.女;publicclassexample{/**Sharedstaticfield.*/publicstaticexamplecurrentExample;/女女Sharedinstancefield.女/publiclongtimestamp;/**Staticintializer.(clinit)*/static{currentExample=newexample();}/**Instanceintializer(init)*/publicexample(){timestamp=System.currentTimeMiIlis();}}附件BlOInitLoader.java[2463]该摘录是InitLoader的源代码,其在加载应用时对其进行修改。importjava.lang.女;importjava.io.*;importjava.net.*;publicclassInitLoaderextendsURLClassLoader{publicInitLoader(URL[]urls){super(urls);}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;try{BufferedInputStreamin=newBufferedInputStream(findResource(name,replace(f.‘,'Γ).concat(".class")).openStreamO);cf=newClassFile(in);}catch(Exceptione){thrownewClassNotFoundException(e.toStringO);}for(inti=O;i〈cf.methods—count;i++){;//Findthe〈clinit>method—infostruct.StringmethodName=cf.constant—pool[cf.methods[i].name_index].toString();if(!methodName.equals(〃<clinit>〃)){continue;}//NowfindtheCode_attributeforthe<clinit>method.for(intj=O;j<cf.methods[i].attributes—count;j++){if(!(cf.methods[i].attributes[j]instanceofCode—attribute))continue;Code_attributeca=(Code_attribute)cf.methods[i].attributes[j];//First,shiftthecode[]downby‘instructions,byte[][]code2=newbyte[ca.code,length+4][];System,arraycopy(ca.code,O,code2,4,ca.code,length);ca.code=code2;//Thenenlargetheconstant—poolby7items.cp_info[]cpi=newcp_info[cf.constant—pool,length+7];System,arraycopy(cf.constant—pool,0,cpi,O,cf.constant—pool·length);[2500]cf.constant—pool=cpi;[2501]cf.constant—pool_count+=7;[2502]//Nowaddtheconstantpoolitemsfortheseinstructions,[2503]starting[2504]//withString.[2505]CONSTANT—String—infocsi=newCONSTANT—String—info([2506]((C0NSTANT_C1ass_info)cf.constant_pool[cf.this_class]).name_index)[2507]cf.constant—pool[cf·constant—pool·length-7]=csi;[2508]//NowaddtheUTFforclass.[2509]C0NSTANT_Utf8_info_ul=newC0NSTANT_Utf8_infoCInitClient");[2510]cf.constant—pool[cf·constant—pool·length-6]=ul;[2511]//NowaddtheCLAsSforthepreviousUTF.[2512]CONSTANT—Class—infocl=[2513]newC0NSTANT_Class_info(cf.constant—pool,lenqth-6);[2514]cf.constant—pool[cf.constant—pool·length-5]=cl;[2515]//NextaddthefirstUTFforNameAndType.[2516]ul=newCONSTANT—Utf8—info("isAlreadyLoaded");[2517]cf.constant—pool[cf·constant—pool·length-4]=ul;[2518]//NextaddthesecondUTFforNameAndType.[2519]ul=newCONSTANT—Utf8—info("(Ljava/lang/string;)Z,r);[2520]cf.constant—pool[cf·constant—pool·length-3]=ul;[2521]//NextaddtheNameAndTypefortheprevioustwoUTFs.[2522]CONSTANT—NameAndType—infonl=newCONSTANT—NameAndType—info([2523]cf.constant—pool·length-4,cf.constant—pool·length-3);[2524]cf.constant—pool[cf·constant—pool·length-2]=nl;[2525]//NextaddtheMethodrefforthepreviousCLASSandNameAndType.[2526]CONSTANT—Methodref—infoml=newCONSTANT—Methodref—info{[2527]cf.constant—pool·length-5,cf.constant—pool·length-2);[2528]cf.constant—pool[cf·constant—pool·length-1]=ml;[2529]//Nowwiththatdone,addtheinstructionsintothecode,[2530]starting[2531]//withLDC.[2532]ca.code=newbyte[3];[2533]ca.code=(byte)19;[2534]ca.code[1]=(byte)(((cf.constant—pool·length-7)>>8)&87[2535]Oxff);[2536]ca.code[2]=(byte)((cf·constant—pool·length_7)&0xff);[2537]//NowAddtheINV0KESTATICinstruction.[2538]ca.code[1]=newbyte[3];[2539]ca.code[l]=(byte)184;[2540]ca.code[1][1]=(byte)(((cf.constant—pool·length-1)>>8)&[2541]Oxff);[2542]ca.code[1][2]=(byte)((cf·constant—pool·length-1)&0xff);[2543]//NextaddthelFEQinstruction.[2544]ca.code[2]=newbyte[3];[2545]ca.code[2]=(byte)153;[2546]ca.code[2][1]=(byte)((4>>8)&0xff);[2547]ca.code[2][2]=(byte)(4&0xff);[2548]//Finally,addtheRETURNinstruction.[2549]ca.code[3]=newbyte[1];[2550]ca.code[3]=(byte)177;[2551]//Lastly,incrementtheCODELENGTHandATTRIBUTELENGTHvalues.[2552]ca.code_length+=10;[2553]ca.attribute_length+=10;[2554]}[2555]}[2556]try{[2557]ByteArrayOutputStreamout=newByteArrayOutputStream();[2558]cf.serialize(out);[2559]byte[]b=out.toByteArray();[2560]returndefineClass(name,b,0,b.length);[2561]}catch(Exceptione){[2562]e.printStackTrace();[2563]thrownewClassNotFoundException(name);[2564]ι[2565]}[2566]}[2567]附件C[2568]Cl.用于单个机器的典型现有技术的终结化[2569]Methodfinalize()[2570]0getstatic#9〈Fieldjava.io.PrintStreamout>[2571]3ldc#24<String,/Deleted...">[2572]5invokevirtual#16〈Methodvoidprintln(javaa.lang.String)>88[2573]8returnC2.用于多个机器的优选终结化Methodfinalize()0invokestatic#3〈MethodbooleanisLastReference()>3ifne76return7getstatie#9<Fieldjava.io.PrintStreamout>10ldc#24<String//Deleted...">12invokevirtual#16<Methodvoidprintln(java.lang.String)>15returnC3.用于多个机器的优选终结化(可替换的)Methodfinalize()0aload_01invokestatic#3<MethodbooleanisLastReference(java.lang.Object))4ifne87return8getstatic#9<Fieldjava.io.PrintStreamout>11ldc#24<String//Deleted...">13invokevirtual#16<Methodvoidprintln(jaava.lang.String))附件C4importjava.lang.~k;publicclassexample{/**Finalizemethod.*/protectedvoidfinalize()throwsThrowable{/I"Deleted..."isprintedoutwhenthisobjectisgarbaged.System,out.println("Deleted...");}}附件C5importjava.lang.~k;importjava.util.*;importjava.net.*;importjava.io.*;publicclassFinalClient{/**Protocolspecificvalues.*/publicfinalstaticintCLOSE=_1;publicfinalstaticintNACK=0;publicfinalstaticintACK=1;publicfinalstaticintFINALIZE_0BJECT=10;89[2612]/**Finalservernetworkvalues.*/publicfinalstaticStringserverAddress=System.getProperty("FinalServer—network—address");publicfinalstaticintserverPort=Integer,parselnt(System.getProperty(“FinalServer—network—port"));/女女TableofglobalID/sforlocalobjects.(hashcode-to-globalIDmappings)*/publicfinalstaticHashtablehashCodeToGlobalID=newHashtable();/**Calledwhenaobjectisbeingfinalized.*/publicstaticbooleanisLastReference(0bjecto){//Firstofall,weneedtoresolvetheglobalIDforobject丨of·//TodothisweusethehashCodeToGlobalIDtable.intglobalID=((Integer)hashCodeToGlobalID.get(o)).intvalue();//Next,wewanttoconnecttotheFinalServer,whichwillinform//usofthefinalizationstatusofthisobject.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.getOutputStream());DataInputStreamin=newDataInputStream(socket.getlnputStream());//0k,nowsendtheserializedrequesttotheFinalServer.out.writelnt(FINALIZE—OBJECT);out.writelnt(globalID);out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremoteside//sendssomething.if(status==NACK){thrownewAssertionError(”Negativeacknowledgement.Requestfailed.”);}elseif(status!=ACK){throwmewAssertionError(〃Unknownacknowledgement:“+status+".Requestfailed.“);}//Next,readina32bitargumentwhichisthecountofthe//remainingfinalizationsintcount=in.readlnt();90[2649]//Ifthecountisequalto1,thenthisisthelastfinalization,//andhenceisLastReferenceshouldbetrue.//Ifhowever,thecountisgreaterthan1,thenthisisnotthe//lastfinalization,andthusisLastReferenceshouldbefalse.booleanisLastReference=(count==1true:false);//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.close();socket,close();//Makesuretoclosethesocket.//ReturnthevalueoftheisLastReferencevariable.returnisLastReference;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}}附件C6importjava.lang.*;importjava.util.*;importjava.net.*;importjava.io.*;publicclassFinalServerimplementsRunnable{/**Protocolpecificvalues*/publicfinalstaticintCLOSE=_1;publicfinalstaticintNACK=O;publicfinalstaticintACK=1;publicfinalstaticintFINALIZE—OBJECT=10;/**FinalServernetwotkvalues.*/publicfinalstaticintserverPort=20001;/女女Tableoffinalizdtionrecords.女/publicfinalstaticHashtablefinalizations=newHashtable();/**Privateinput/outputobjects.*/privateSocketsocket=null;privateDataOutputStreamoutputStream;privateDataInputStreaminputStream;privateStringaddress;publicstaticvoidmain(String[]s)91[2688]operation}/necessarythrowsException{System,out.println("FinalServer_network_address="+InetAddress.getLocalHost().getHostAddress());System,out.println("FinalServer_network_port="+serverPort);//Createaserversockettoacceptincominginitialization//connections.ServerSocketserverSocket=newServerSocket(serverPort);while(!Thread,interrupted()){//Blockuntilanincominginitializationoperationconnection.Socketsocket=serverSocket.accept();//CreateanewinstanceofInitServertomanagethis//initializationoperationconnection.newThread(newFinalServer(socket)).start();-k*Constructor.InitializethisnewFinalServerinstancewithandvalues'resourcesforoperation.*publicFinalServer(Sockets){socket=s;try{outputStream=newDataOutputStream(s.qetOutputStream())inputStream=newDataInputStream(s.getlnputStream());address=s.getlnetAddress().getHostAddress();}catch(IoExceptione){thrownewAssertionError('Exception:"+e.toString())/~k-kMaincodebody.Decodeincomingfinalizationoperationrequestsexecuteaccordingly.*/publicvoidrun(){try{//Allcommandsareimplementedas32bitintegers.//Legalcommandsarelistedinthe"protocolspecific//fieldsabove.intcommand=inputStream.readlnt();92[2723]//ContinueprocessingcommandsuntilaCLOSEoperation.while(command!=CLOSE){if(comimnd==FINALIZE—OBJECT){//Thisisa//FmALIZE—OBJECT//operation.//ReadintheglobalIDoftheobjecttobefinalized.intglobalID=inputStream.readlnt();//Synchronizeonthefinalizationstableinordertoensure[2731]//thread-safety.synchronized(finalizations){//Locatethepreviousfinalizationsentryforthis//object,ifany.Integerentry=(Integer)finalizations·get(newlnteger(globalID));if(entry==null){thrownewAssertionError("Unknownobject.“);}elseif(entry.intValue()<1){thrownewAssertionError("Invalidcount.“);}elseif(entry.intValue()==1){//Countoflmeans//thisisthelast//reference,hence//removefromtable.finalizations.remove(newlnteger(globalID));//SendapositiveacknowledgementtoFinalClient,//togetherwith,thecountofremainingreferences-//whichinthiscaseis1.outputStream.writelnt(ACK);outputStream.writelnt(1);outputStream.flush();}else{//Thisisnotthelastremaining//reference,ascountisgreaterthan1.//Decrementcountby1.finalizations.put(newInteger(globalID),newlnteger(entry.intValue()-1));//SendapositiveacknowledgementtoFinalClient,//togetherwiththecountofremainingreferencesto//thisobject-whichinthiscaseofmustbevalue//"entry.intValue()".outputStream.writelnt(ACK);93[2762]outputStream.writelnt(entry.intValue());outputStream.flush();}}}else{//Unknowncommand.thrownewAssertionError(〃Unknowncommand.Operationfailed.〃);}//Readinthenextcommand.command=inputStream.readlnt();}}catch(Exceptione){thrownewAssertionError("Exception:“+e.toStringO);}finally{try{//Closingdown.Cleanupthisconnection.outputStream.flush();outputStream.close();inputStream.close();socket,close();}catch(Throwablet){t.printStackTraceO;}//Garbagethesereferences.outputStream=null;inputStream=null;socket=null;}}}附件C7FinalLoader.java该摘录是FinalLoader的源代码,其在加载应用时对其进行修改。importjava.lang.*;importjava.io.*;importjava.net.*;publicclassFinalLoaderextendsURLClassLoader{publicFinalLoader(URL[Juris){super(urls);94[2801]}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;try{BufferedInputStreamin=newBufferedInputStream(findResource(name,replace(f.‘,'Γ).concat(".class")).openStreamO);cf=newClassFile(in);}catch(Exceptione){thrownewClassNotFoundException(e.toStringO);}for(inti=O;i<cf.methods—count;i++){//Findthefinalizemethod—infostruct.StringmethodName=cf.constant—pool[cf.methods[i].name_index].toStringO;if(!methodName.equals(/rfinalize'7)){continue;}//NowfindtheCode_attributeforthefinalizemethod.for(intj=O;j<cf.methods[i].attributes_count;j++){if(!(cf.methods[i].attributes[j]instanceofCode_attribute))continue;Code_attributeca=(Code_attribute)cf.methods[i].attributes[j];//First,shiftthecode[]downby‘instructions.byte[][]code2=newbyte[ca.code,length+4][];System,arraycopy(ca.code,O,code2,4,ca.code,length);ca.code=code2;//Thenenlargetheconstant—poolby6items.cp_info[]cpi=newcp_info[cf.constant—pool,length+6];System,arraycopy(cf.constant—pool,0,cpi,O,cf.constant—pool,length);cf.constant—pool=cpi;cf.constant—pool_count+=6;//NowaddtheUTFforclass.C0NSTANT_Utf8_infoul=newC0NSTANT_Utf8_info("FinalClient");cf.constant—pool[cf.constant—pool,length—6]=ul;[2836]info{NameAndType.starting[2861][2862]8)&Oxff);//NowaddtheCLASSforthepreviousUTF.CONSTANT_Class_infocl=newCONSTANT_Class_info(of.constant_pool.length-6);cf.constant_pool[cf.constant_pool.length-5]=cl;//NextaddthefirstUTFforNameAndType.ul=newC0NSTANT_Utf8_info("isLastReference");cf.constant_pool[cf.constant_pool.length-4]=ul;//NextaddthesecondUTFforNameAndType.ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;)Z");cf.constant_pool[cf.constant_pool.length-3]=ul;//NextaddtheNameAndTypefortheprevioustwoUTFs.CONSTANT_NameAndType_infonl=newC0NSTANT_NameAndType_cf.constant_pool.length-4,cf.constant_pool.length-3);cf.constant_pool[cf.constant_Pool.length-2]=nl;//NextaddtheMethodrefforthepreviousCLASSandC0NSTANT_Methodref_infoml=newC0NSTANT_Methodref_info{cf.constant_pool.length-5,cf.constant_pool.length-2);cf.constant_pool[cf.constant_pool.length-1]=ml;//Nowwiththatdone,addtheinstructionsintothecode,//withLDC.ca.code=newbyte[1];ca.code=(byte)42;//NowAddtheINVOKESTATICinstruction.ca.code[1]=newbyte[3];ca.code[l]=(byte)184;ca.code[1][1]=(byte)(((cf.constant_pool.length-1)>>ca.code[1][2]=(byte)((cf.constant_pool.length-1)&0xff);//NextaddtheIFNEinstruction.ca.code[2]=newbyte[3];ca.code[2]=(byte)154;ca.code[2][1]=(byte)((4>>8)&0xff);ca.code[2][2]=(byte)(4&0xff);//Finally,addtheRETURNinstruction.ca.code[3]=newbyte[1];[2872]ca.code[3]=(byte)177;//Lastly,incrementtheC0DE_LENGTHandATTRIBUTE_LENGTHvalues.ca.code_length+=8;ca.attribute—length+=8;}}try{ByteArrayOutputStreamout=newByteArrayOutputStream();cf.serialize(out);byte[]b=out.toByteArray();returndefineClass(name,b,0,b.length);}catch(Exceptione){e.printStackTrace();thrownewClassNotFoundException(name);}}}附件DlMethodvoidrun()Ogetstatic#2<Fieldjava.lang.0bjectL0CK>3dup4astore_l5monitorenter6getstatic#3<Fieldintcounter)9iconst_l10iadd11putstatic#3<Fieldintcounter)14aload_l15monitorexit16return附件D2Methodvoidrun()Ogetstatic#2<Fieldjava.lang,ObjectL0CK>3dup4astore_l5dnp6monitorenter7invokestatic#23<MethodvoidacquireLock(javaa.lang.Object))[2910]10getstatic#3〈Fieldintcounter)[2911]13iconSt—1[2912]14iadd[2913]15putstatic#3〈Fieldintcounter)[2914]18aload_l[2915]19dup[2916]20invokestatic#24〈MethodvoidreleaseLock(java.lang.Object)>[2917]23monitorexit[2918]24return[2919]附件D3[2920]importjava.lang.;[2921]pubIicclassexample{[2922]/**Sharedstaticfield.*/[2923]publicfinalstaticObjectLOCK=newObject();[2924]/女女Sharedstaticfield.女/[2925]publicstaticintcounter=0;[2926]/**Examplemethodusingsynchronization.Thismethodservesto[2927]illustratetheuseofsynchronizationtoimplementthread-safe[2928]modificationofasharedmemorylocationbypotentiallymultiple[2929]threads.*/[2930]publicvoidrun(){[2931]//Firstacquirethelock,otherwiseanymemorywriteswedowillbe[2932]//pronetorace-conditions.[2933]synchronized(LOCK){[2934]//Nowthatwehaveacqdiredthelbck,wecansafelymodifymemory}elseif(status!=ACK){thrownewAssertionError(〃Unknownacknowledgement:“+status+".Requestfailed.");}//Closedowntheconnection.out.writelnt(CLOSE);out.flush(};out.close();in.close();socket,close();//Makesuretoclosethesocket.//Thisisagoodacknowledgement,thuswecanreturnnowbecause//globallockisnowacquired.return;}catch(IOExceptione){thrownewAssertionError("Exception:“+e.toStringO);}}/**Calledwhenanapplicationistoreleasealock.*/publicstaticvoidreleaseLock(Objecto){//Firstofall,weneedtoresolvetheglobalIDforobject'o'.//TodothisweusethehashCodeToGlobalIDtable.intglobalID=((Integer)hashCodeToGlobalID.get(o)).intValue();try{//Next,wewanttoconnecttotheLockServer,whichrecordsusas//theownerofthegloballockforobject'o'.Socketsocket=newSocket(serverAddress,serverPort);DataOutputStreamout=newDataOutputStream(socket.get0utputStream());DataInputStreamin=newDataInputStream(socket.getlnputStreamO);//0k,nowsendtheserializedrequesttothelockserver.out.writelnt(RELEASE_L0CK);out.writelnt(globalID);out.flush();//Nowwaitforthereply.intstatus=in.readlnt();//Thisisablockingcall.Sowe//willwaituntiltheremotesideHsendssomething.100[3020]if(status==NACK){thrownewAssertionError("Negativeacknowledgement.Requestfailed.");}elseif(status!=ACK){thrownewAssertionError("Unknownacknowledgement:"+status+".Requestfailed.");}//Closedowntheconnection.out.writelnt(CLOSE);out.flush();out.close();in.close();socket,close();//Makesuretoclosethesocket.//Thisisagoodacknowledgement,returnbecausegloballockis//nowreleased.return;}catch(IOExceptione){thrownewAssertionError("Exception:"+e.toString());}}}附件D5importjava.lang.~k;importjava.util.*;importjava.net.*;importjava.io.*;publicclassLockServerimplementsRunnable{/**Protocolspecificvalues*/publicfinalstaticintCLOSE=_1;publicfinalstaticintNACK=O;publicfinalstaticintACK=1;publicfinalstaticintACQUIRELOCK=10;publicfinalstaticintRELEASELOCK=20;/**LockServernetworkvalues.*/publicfinalstaticintserverPort=20001;/**Tableoflockrecords.*/publicfinalstaticHashtablelocks=newHashtable();/-k-kLinkedlistofwaitingLockManagerobjects.~k/publicLockServernext=null;101[3059[3060[3061[3062[3063[3064[3065[3066[3067[3068[3069/**AddressofremoteLockClient.*/publicfinalStringaddress;/**Privateinput/outputobjects.*/privateSocketsocket=null;privateDataOutputStreamoutputStream;privateDataInputStreaminputStream;publicstaticvoidmain(String[]s)throwsException{System,out.println("LockServer_network_address=+InetAddress.getLocalHost().getHostAddress());System.out.println(LockServer_network_port+serverPort)execute-k//Createaserversockettoacceptincominglockoperation//connectiohs.ServerSocketserverSocket=newServerSocket(serverPort);while(!Thread,interrupted()){//Blockuntilanincominglockoperationconnection.Socketsocket=serverSocket.accept();//CreateanewinstanceofLockServertomanaqethislock//operationconnection.newThread(newLockServer(socket)).start();*Constructor.InitialisethisnewLockServerinstancewithresourcesforoperation.*/publicLockServer(Sockets){socket=s;try{outputStream=newDataOutputStream(s.getOutputStream())inputStream=newDataInputStream(s.getlnputStream());address=s.getlnetAddress().getHostAddress();}catch(IOExceptione){thrownewAssertionError("Exception:"+e.toString());~k-kMaincodebody.Decodeincominglockoperationrequestsandaccordingly.*102[3095]values‘publicvoidrun(){try{//Allcommandsareimplementedas32bitintegers.//Legalcommnandsarelistedinthe"protocolspecific//fieldsabove,intcommand=inputStream.readlnt();//ContinueprocessingcommandsuntilaCLOSEoperation,while(command!=CLOSE){if(command==ACQUIRELOCK){,Thisisan/ACQUIRE_L0CK//operation.//ReadintheglobalIDoftheobjecttobelocked,intglobalID=inputStream.readlnt();//Synchronizeonthelockstableinordertoensurethread-//safety.synchronized(locks){//Checkforanexistingownerofthislock.LockServerlock=(LockServer)locks,get(newlnteger(globalID));if(lock==null){//No-onepresentlyownsthislock,//soacquireit.locks,put(newlnteger(globalID),this);acquireLock();//Signaltotheclientthe//successfulacquisitionofthis//lock.}else{//Alreadyowned.Appendourselves//toendofqueue.//Searchfortheendofthequeue.(Implementedas//linked-list)while(lock,next!=null){lock=lock,next;lock,next=this;//Appendthislockrequestatend.}elseif(command==RELEASE_L0CK){//Thisisa//RELEASE_L0CK//operation.103[3133]//ReadintheglobalIDoftheobjecttobelocked.intglobalID=inputStream.readlnt();//Synchronizeonthelockstableinordertoensurethread—//safety.synchronized(locks){//Checktomakesurewearetheownerofthislock.LockServerlock=(LockServer)locks,get{newInteger(globalID));if(lock==null){thrownewAssertionError(〃Unlocked.Releasefailed.〃);}elseif(lock,address!=this,address){thrownewAssertionError("Tryingtoreleasealock"+"whichthisclientdoesn/town.Release“+"failed.“);}lock=lock,next;lock.acquireLock();//Signaltotheclientthe//successfulacquisitionofthis//lock.//Shiftthelinkedlistofpendingacquisitionsforward//byone.locks,put(newlnteger(globalID),lock);//Clearstalereference.next=null;}releaseLock();//Signaltotheclientthesuccessful//releaseofthislock.}else{//Unknowncommand.thrownewAssertionError(〃Unknowncommand.Operationfailed.〃);}//Readinthenextcommand.command=inputStream.readlnt();}}catch(Exceptione){thrownewAssertionError("Exception:“+e.toStringO);}finally{try{//Closingdown.Cleanupthisconnection.[3172]outputStream.flush();outputStream.close();inputStream.close();socket,close();}catch(Throwablet)(t.printStackTrace();}HGarbagethesereferences.outputStream=null;inputStream=null;socket=null;}}I±±SendapositiveacknowledgementofanACQUIRE—LOCKoperation.女/publicvoidacquireLock()throwsIOException{outputStream.writelnt(ACK);outputStream.flush();}/**SendapositiveacknowledgementofaRELEASE_L0CKoperation.女/publicvoidreleaseLock()throwsIOException{outputStream.writelnt(ACK);outputStream.flush();}}附件D6LockLoader.java该摘录是LockLoader的源代码,其在加载应用时对其进行修改。importjava.lang.*;importjava.io.*;importjava.net.*;publicclassLockLoaderextendsURLVlassLoader{publicLockLoader(URL[]urIs){super(urls);}protectedClassfindClass(Stringname)throwsClassNotFoundException{ClassFilecf=null;105[3209]try{[3210]BufferedInputStreamin=[3211]newBufferedInputStream(findResource(name,replace('.',[3212]'/').concat(".class")).openStream());[3213]cf=newClassFile(in);[3214]}catch(Exceptione)(thrownewClassNotFoundException(e.tostringO);}[3215]//Class-widepointerstotheenterindexandexitindex.[3216]intenterindex=-1;[3217]intexitindex=-1;[3218]for(inti=0;i<cf.methodscount;i++){[3219]for(intj=0;j<cf.methods[i].attributes_count;j++){[3220]if(!(cf.methods[i].attributes[j]instanceofCode_attribute))[3221]continue;[3222]Code_attributeca=(Code_attribute)cf.methods[i].attributes[j][3223]booleanchanged=false;[3224]for(intz=0;z<ca.code,length;z++){[3225]if((ca.code[z]&0xff)==194){//Opcodefora[3226]//M0NIT0RENTER[3227]//instruction.[3228]changed=true;[3229]//Next,realignthecodearray,makingroomforthe[3230]Ilinsertions.[3231]byte[][]code2=newbyte[ca.code,length+2][];[3232]System,arraycopy(ca.code,0,code2,0,z);[3233]code2[z+1]=ca.code[z];[3234]System,arraycopy(ca.code,z+1,code2,z+3,[3235]ca.code,length-(z+1));[3236]ca.code=code2;[3237]//Next,inserttheDUPinstruction.[3238]ca.code[z]=newbyte[1];[3239]ca.code[ζ]=(byte)89;[3240]//Finally,inserttheINV0KESTATICinstruction.[3241]if(enterindex==_1){[3242]//Thisisthefirsttimethisclassisencourtering[3243]the[3244]//acquirelockinstruction,sohavetoaddittothe//constantpool.cp_info[]cpi=newcp_info[cf.constant_pool.length+6];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cf.constant_pool=cpi;cf.constant_pool_count+=6;C0NSTANT_Utf8_infoul=newC0NSTANT_Utf8_info("LockClient");cf.constant_pool[cf.constant_pool.length-6]=ul;C0NSTANT_Class_infocl=newC0NSTANT_Class_info{cf.constant_pool_count_6);cf.constant_pool[cf.constant_pool.length-5]=cl;ul=newC0NSTANT_Utf8_info("acquireLock");cf.constant_pool[cf.constant_pool.length-4]=ul;ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;)V");cf.constant_pool[cf.constant_pool.length-3]=ul;CONSTANT_NameAndType_infonl=newCONSTANT_NameAndType_info{cf.constant_pool.length-4,cf.constant_pool.Iength-3);cf.constant_pool[cf.constant_pool.length-2]=nl;C0NSTANT_Methodref_infoml=newC0NSTANT_Methodref_info(cf.constant_pool.length-5,cf.constant_pool.Iength-2);cf.constant_pool[cf.constant_pool.length-1]=ml;enterindex=cf.constant_pool.length-1;}107[3273]ca.code[z+2]=newbyte[3];ca.code[z+2]=(byte)184;ca.code[z+2][1]=(byte)((enterindex>>8)&0xff);ca.code[z+2][2]=(byte)(enterindex&Oxff);//Andlastly,increasetheCODE_LENGTHandATTRIBUTE_LENGTH//values.ca.code_length+=4;ca.attribute—length+=4;ζ+=1;}elseif((ca.code[z]&Oxff)==195){//Opcodefora//M0NIT0REXITIlinstruction.changed=true;//Next,realignthecodearray,makingroomforthe//insertions.byte口[]code2=newbyte[ca.code,length+2][];System,arraycopy(ca.code,0,code2,0,z);code2[z+l]=ca.code[z];System,arraycopy(ca.code,z+1,code2,z+3,ca.code,length-(z+1));ca.code=code2;//Next,inserttheDUPinstruction.ca.code[z]=newbyte[l];ca.code[ζ]=(byte)89;//Finally,inserttheINV0KESTATICinstruction.if(exitindex==_1){//Thisisthefirsttimethisclassisencourteringthe//acquirelockinstruction,sohavetoaddittothe//constantpool.cp_info[]cpi=newcp_info[cf.constant_pool.length+6];System,arraycopy(cf.constant_pool,0,cpi,0,cf.constant_pool.length);cf.constant_pool=cpi;cf.constant_pool_count+=6;[3309]CONSTANTUtf8_infoul=newC0NSTANT_Utf8_info("LockClient“);cf.constant_pool[cf.constant_pool.length-6]=ul;CONSTANT_Class_infocl=newCONSTANT_Class_info(cf.constant_pool_count_6);cf.constant_pool[cf.constant_pool.length-5]=cl;ul=newC0NSTANT_Utf8_info("releaseLock");cf.constant_pool[cf.constant_pool.length-4]=ul;ul=newC0NSTANT_Utf8_info("(Ljava/lang/Object;)V");cf.constant_pool[cf.constant_pool.length-3]=ul;CONSTANT_NameAndType_infonl=newCONSTANT_NameAndType_info{cf.constant_pool.length-4,cf.constant_pool.Iength-3);cf.constant_pool[cf.constant_pool.length-2]=nl;CONSTANT_Methodref_infoml=newCONSTANT_Methodref_info(cf.constant_pool.length-5,cf.constant_pool.Iength-2);cf.constant_pool[cf.constant_pool.length-1]=ml;exitindex=cf.constant_pool.length-1;}ca.code[z+2]=newbyte[3];ca.code[z+2]=(byte)184;ca.code[z+2][1]=(byte)((exitindex>>8)&0xff);ca.code[z+2][2]=(byte)(exitindex&Oxff);//Andlastly,increasetheCODE_LENGTHandATTRIBUTE_LENGTH//values.ca.code_length+=4;109[3339]ca.attribute_length+=4;ζ+=1;7Ifwechangedthismethod,thenincreasethestacksizebyone.if(changed){ca.max_stack++;7Justtomakesure.try{ByteArrayOutputStreamout=newByteArrayOutputStream();cf.serialize(out);byte[]b=out.toByteArray();returndefineClass(name,b,0,b.length);}catch(Exceptione){thrownewClassNotFoundException(name);权利要求一种多计算机系统,所述多计算机系统具有至少一个应用程序,所述应用程序在通过通信网络互连的多个计算机上同时运行,其中所述应用程序的不同部分基本上同时在所述多个计算机中不同的计算机上执行,其中对于每个所述部分,创建同样多个基本上相同的对象,每个所述对象在对应的计算机中,且其中每个所述计算机的所有读请求仅从读在请求计算机中创建的对象来满足。2.如权利要求1所述的系统,其中所述多个基本上相同的对象的每个具有基本上相同的名称。3.如权利要求2所述的系统,其中所述的相同命名对象的每个的初始内容是基本上相同的。4.如权利要求2或3所述的系统,其中当各个所述多个计算机都不再需要引用各个相同对象的组的其对应对象时,全体删除所述相同对象的组。5.如权利要求4所述的系统,其中每个所述计算机包括分布式运行时间装置,其中每个所述计算机的分布式运行时间装置能够与所有其他计算机通信,由此如果运行在所述计算机之一上的所述应用程序的一部分不再需要引用该计算机中的对象,则将不再引用的对象的标识由所述的一个计算机的分布式运行时间装置传送给可由所有其他计算机访问的共享表。6.如权利要求5所述的系统,其中通过插入终结化例程,在加载之前、期间或之后,对每个所述应用程序进行修改,以对其中所述应用程序不再需要引用对象的每个实例进行修改。7.如权利要求6所述的系统,其中所述的所插入的终结化例程修改预先存在的终结化例程,以便在所有计算机不再需要引用其对应对象时使所述预先存在的终结化例程能够执行,并在至少一个计算机确实需要引用对应对象时,禁止预先存在的终结化例程。8.如权利要求2-4中任意一项所述的系统,包括可应用于所有所述计算机的锁定装置,其中想要利用其中所命名的对象的任何计算机从所述锁定装置获取授权锁定,所述授权锁定允许所述利用,并防止所有其他计算机利用其对应的命名对象,直到所述授权锁定被放弃9.如权利要求8所述的系统,其中所述锁定装置包括获取锁定例程和释放锁定例程,且两个所述例程都包括于对运行在所有所述计算机上的所述应用程序所作的修改中。10.如权利要求9所述的系统,其中所述锁定装置进一步包括共享表,该共享表列出任何所述计算机所使用的所述命名对象、每个所述对象的锁定状态和任何未决的锁定获取的队列。11.如权利要求10所述的系统,其中所述锁定装置位于不运行所述应用程序且连接至所述通信网络的附加计算机内。12.如权利要求11所述的系统,其中通过插入所述获取锁定例程和所述释放锁定例程,在加载之前、期间或之后,对每个所述应用程序进行修改,以对其中所述应用程序分别获取和释放对对象的锁定的每个实例进行修改。13.如权利要求1-12中任意一项所述的系统,其中每个所述计算机包括分布式更新装置,其中每个所述计算机的分布式更新装置能够与所有其他计算机通信,以使得如果运行在所述计算机之一上的所述应用程序的一部分改变该计算机中对象的内容,则将所述对象的内容的改变通过所述一个计算机的分布式更新装置传播到所有其他计算机,以改变每个所述其他计算机中的对应对象的内容。14.如权利要求13所述的系统,其中所有所述分布式更新装置以明显小于本地存储器读速率的数据传送速率经由所述通信链路来通信。15.如权利要求1-14中任意一项所述的系统,其中通过插入更新传播例程,在加载之前、期间或之后,对每个所述应用程序进行修改,以对所述应用程序在其处写入存储器的每个实例进行修改,所述更新传播例程将一个计算机的每个存储器写传播到所有所述其他计算机。16.如权利要求1-15中任意一项所述的系统,其中通过插入初始化例程,在加载之前、期间或之后,对每个所述应用程序进行修改,以对所述应用程序在其处创建对象的每个实例进行修改,所述初始化例程将一个计算机新创建的每个对象都传播到所有所述其他计算机。17.如权利要求16所述的系统,其中所述的所插入的初始化例程修改预先存在的初始化例程,以便使所述预先存在的初始化例程能够在创建了所述同样多个对象的第一个对象时执行,并在创建了所述的同样多个对象的所有后续对象时,禁止所述预先存在的初始化例程。18.如权利要求17所述的系统,其中所述应用程序是根据从以下构成的过程组中所选的过程来修改的加载时的重新编译、加载前的预编译、加载前的编译、正好适时的编译以及加载后且在应用程序的相关部分执行前的重新编译。19.如权利要求18所述的系统,其中所述被修改的应用程序根据从以下构成的组中所选的过程而被传送到所有所述计算机主/从传送、分支传送和级联传送。20.如权利要求1-19中任意一项所述的系统,其中分配给所述应用程序或每个所述应用程序的本地存储器容量是基本上相同的,并且对所述应用程序或每个所述应用程序可用的总存储器容量是所述的所分配的存储器容量。21.如权利要求1-20中任意一项所述的系统,其中所述计算机的至少一些是由不同制造商来制造的和/或具有不同的操作系统。22.—种在多个计算机上同时运行至少一个应用程序的方法,所述计算机借助于通信网络来互连,所述方法包括以下步骤(i)在所述计算机中的不同计算机上执行所述应用程序的不同部分,以及对于每个所述部分,创建同样多个基本上相同的对象,所述对象每个在对应的计算机中;以及()通过仅从读在请求计算机中创建的对象来满足每个所述计算机的所有读请求。23.如权利要求22所述的方法,进一步包括以下步骤(iii)以基本上相同的名称对每个所述多个基本上相同的对象命名。24.如权利要求22或23中所述的方法,进一步包括以下步骤(iv)如果运行在所述计算机之一上的所述应用程序的一部分改变该计算机中对象的内容,则将所述对象的内容的改变经由所述通信网络传播到所有其他计算机,以改变每个所述其他计算机中的对应对象的内容。25.如权利要求24中所述的方法,进一步包括以下步骤(ν)通过插入更新传播例程,在加载之前、期间或之后,对所述应用程序进行修改,以对所述应用程序在其处写入存储器的每个实例进行修改,所述更新传播例程将一个计算机的每个存储器写传播到所有所述其他计算机。26.如权利要求25所述的方法,进一步包括以下步骤(vi)利用从以下构成的过程组中所选的过程来修改所述应用程序加载时的重新编译、加载前的预编译、加载前的编译、正好适时的编译以及在加载之后且在应用程序的相关部分执行之前的重新编译。27.如权利要求26所述的方法,进一步包括以下步骤(vii)利用从以下构成的组中所选的过程将所述的修改后的应用程序传送到所有所述计算机主/从传送、分支传送和级联传送。28.如权利要求25-27中任意一项所述的方法,进一步包括下列步骤(viii)以明显小于本地存储器读速率的数据传送速率来传送构成更新数据传输的所述本地存储器写。29.如权利要求23-28中任意一项所述的方法,进一步包括下列步骤(ix)将所述的相同命名对象的每个的初始内容创建为基本上相同。30.如权利要求29所述的方法,进一步包括以下步骤(χ)如果在所述计算机之一上运行的所述应用程序的部分在该计算机中创建对象,那么所创建的对象经由所述通信网络被传播到所有其他计算机。31.如权利要求30所述的方法,进一步包括以下步骤(xi)通过插入初始化例程,在加载之前、期间或之后,对所述应用程序进行修改,以对所述应用程序在其处创建对象的每个实例进行修改,所述初始化例程将一个计算机创建的每个对象传播到所有所述其他计算机。32.如权利要求31所述的方法,进一步包括以下步骤(xii)利用从以下所构成的过程的组中所选的过程,对所述应用程序进行修改加载时的重新编译、加载之前的预编译、加载之前的编译、正好适时的编译以及在加载之后且在应用程序的相关部分执行之前的重新编译。33.如权利要求32所述的方法,进一步包括以下步骤(xiii)利用从以下构成的组中所选的过程,将所修改的应用程序传送到所有所述计算机主/从传送、分支传送和级联传送。34.如权利要求22-33中任意一项所述的方法,进一步包括下列步骤(xiv)当所有所述多个计算机均不再需要引用其对应对象时,将所有所述的相同对象全体删除。35.如权利要求34所述的方法,进一步包括以下步骤(xv)为每个所述计算机提供分布式运行时间装置,以经由所述通信网络在所述多个计算机之间进行通信。36.如权利要求35所述的方法,进一步包括以下步骤(xvi)提供可由每个所述分布式运行时间装置来访问的共享表,其中存储了不再需要访问对象的任何计算机的标识连同该对象的标识。37.如权利要求36所述的方法,进一步包括以下步骤(xvii)将计数器装置与所述共享表关联,所述计数器装置存储对不再需要访问所述对象的所述计算机数量的计数。38.如权利要求37所述的方法,进一步包括以下步骤(xviii)提供附加的计算机,所述共享程序不在所述附加的计算机上运行,且所述附加的计算机容纳所述共享表和计数器,所述的附加的计算机连接至所述通信网络。39.如权利要求22-34中任意一项所述的方法,进一步包括下列步骤(xviv)要求想要利用其中的命名对象的任何所述计算机获取授权锁定,所述授权锁定允许所述利用,且其防止所有其他计算机来利用其对应的命名对象,直到所述授权锁定被放弃。40.如权利要求39所述的方法,进一步包括以下步骤(xx)为每个所述计算机提供分布式运行时间装置,以经由所述通信网络在所述多个计算机之间进行通信。41.如权利要求40所述的方法,进一步包括以下步骤(xxi)提供可由每个所述分布式运行时间装置来访问的共享表,其中存储了当前需要访问对象的任何计算机的标识连同该对象的标识。42.如权利要求41所述的方法,进一步包括以下步骤(xxii)将计数器装置与所述共享表关联,所述计数器装置存储对寻求访问所述对象的所述计算机数量的计数。43.如权利要求42所述的方法,进一步包括以下步骤(xxiii)提供附加的计算机,所述的共享程序不在所述附加的计算机上运行,且所述附加的计算机容纳所述共享表和计数器,所述的附加的计算机连接至所述通信网络。44.一种单个计算机,被布置为与至少一个其他同样的计算机合作以形成权利要求1至21中任意一项所述的多计算机系统。全文摘要本发明公开了一种修改的计算机架构,其使得应用程序(50)能够在多个计算机(M1、...Mn)上同时运行。每个计算机处的共享存储器被以修改和/或覆写来更新,以便使所有存储器读请求在本地得到满足。在初始程序加载(75)期间,或相似过程期间,识别导致存储器被重写或操纵的指令(92)。此外,公开了JAVA语言类和对象的初始化(162,163),这样所有计算机的所有存储器位置以相同的方式被初始化。还公开了JAVA语言类和对象的终结化(162,163),这样仅当不再需要所有机器上的最后的类或对象时,才会发生终结化。文档编号G06F15/16GK101908001SQ201010247309公开日2010年12月8日申请日期2005年4月22日优先权日2004年4月22日发明者约翰·马修·霍尔特申请人:瓦拉泰克有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1