




已阅读5页,还剩67页未读, 继续免费阅读
(计算机软件与理论专业论文)java虚拟机的内存管理策略的研究.pdf.pdf 免费下载
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
摘要 摘要 虚拟机( x r m u a lm a c h i n e ,v m ) 是相对于我们平常所用的实际的计算机而言的 一个概念,它是一个假想的模拟实际计算机进行工作的软件系统。虚拟机的优点 之一就是计算机程序可以在不同的操作系统之间复用,即实现程序的跨平台,j a v a 虚拟机的设计思想正体现了这一特点。 本文以j a v a 虚拟机中的内存管理技术为主要研究对象,比较深入的分析和研 究了其中的一些关键技术,并且基于传统的分代式收集算法,提出了一种适合于 嵌入式系统的内存管理策略。本文的主要工作如下: 首先对于对象在内存中的布局进行改进,将对象引用域和其他类型域分开存 放,对象不同层次的继承数据采用四字节( 对象引用数据类型长度) 对齐方式来 优化内存布局,便于收集器找到对象引用区。 其次在旧生代和新生代的处理中,分别采用了标记清除和复制算法,来进行代 中垃圾内存的收集。对新生代和旧生代,提出了动态划分的思想。在活动对象的 提升过程中,提出了d e s t 缓冲区的概念,用来改进垃圾收集的效率。在新生代中, 对用于复制算法的两个分区以及d e s t 缓冲区,提出了动态调整的算法。 最后基于简单的例子,对本文中的算法的缺点加以指出,并提出如何避免。 关键词:j a v a 虚拟机,分代,垃圾收集,嵌入式 a b s t r a c t v i r t u a lm a c h i n e ,w h i c hs t a n d sa g a i n s tw i t ho u ro r d i n a r yr e a l i s t i c c o m p u t e r ,i sj u s tac o n c e p t i t sa ni m a g i n i n gs o f t w a r es y s t e m , w h i c hc a n b eu s e dt os i m u l a t et h er e a lc o m p u t e r t h ea d v a n t a g eo fv i r t u a lm a c h i n e i s i tc a nr e u s et h ep r o g r a m so nt h ed i f f e r e n to p e r a t i n gs y s t e m , s a yt h e p o r t a b i l i t yo fa p p l i c a t i o np r o g r a m t h ed e s i g nm e c h a n i s mo fj a v av i r t u a l m a c h i n er e f l e c t st h i sc h a r a c t e rv e r yw e l l t h i sp a p e rt a k e st h em e m o r ym a n a g e m e n ti nj a v av i r t u a lm a c h i n ea st h e r e s e a r c hf i e l d ,d e e p l ya n a l y s i sa n dr e s e a r c ht h ek e yt e c h n i q u ei ni t b a s e d o nt h et r a d i t i o n a lg e n e r a t i o ng a r b a g ec o l l e c t i o n ,t h ea u t h o rs u p p l i e sa n e wm e m o r ym a n a g e m e n tm e t h o d ,w h i c hi ss u i t a b l ef o rt h ee m b e d d e ds y s t e 札 t h ew o r ko nt h i sp a p e rc a nb ed e s c r i b e da sf o l l o w s : f i r s t ,t h en e wm e t h o di m p r o v e dt h eo b j e c t sl a y o u ti nt h em e m o r y ,p u t t h ed a t aa n dr e f e r e n c ei nd i f f e r e n td o m a i n ,a n du s et h e4b y t e sa l i g n m e n t t ow h i c he a s et h eg a r b a g ec o l l e c t o rt of i n dt h eo b j e c tr e f e r e n c ed o m a i n s e c o n d t h en e wm e t h o du s e st h em a r k - a n d - s w e e pm e c h a n i s mt oc l e a nu p t h eg a r b a g em e m o r yi nt h eo l dg e n e r a t i o n ,a n du t i l i z e st h ec o p ym e c h a n i s m f o rn e wg e n e r a t i o n t h ed y n a m i cg e n e r a t i o n - d i v i s i o nw a si m p o r t e di n t ot h e n e wm e t h o d d u r i n gt h el o n g l i f eo b j e c t s p r o m o t i o n ,i tu s et h ed e s tb l o c k a sb u f f e r ,t of a c i l i t a t ea n ds p e e du pt h ep r o m o t i o np r o g r e s s i nt h en e w g e n e r a t i o n ,t h ed y n a m i cs i z e - a d j u s tm e t h o dw a su s e d ,t or e d u c et h e i n f l u e n c ec a u s e db yt h eg a r b a g ec o l l e c t o r a tl a s t ,t h ea u t h o rg i v e sas i m p l ee x a m p l e ,t os h o wt h ed i s a d v a n t a g e o ft h i sn e wm e t h o d ,a n dp o i n t so u th o wt oa v o i di t k e y r o r d s :j a v a v i r t u a lm a c h i n e ,g e n e r a t i o n ,g a r b a g ec o l l e c t i o n , e m b e d d e d 独创性声明 本天声瞻翳至交煞学位论文蔻本a 在导师指导下进行瓣硬究王 作及取得的研究成果。据我所知,除了文中特别加以标注和致谢的地 方羚,论文巾苓毽含其他a 邑经爱褒或撰写过熟辨究震暴,也琴蕾含 为获得电子科技大学或熟它教育机构的学位或谜书而使用过的材料。 与我一嚣工作戆霾意对零磋究囊傲黪任嚣贡皴均基在论文孛终了锈 确的说明并袭示谢意。 签名: 袈鍪毯霹裳:砷年争旁基 关手论文使耀授权的说辨 本学位论文作者完全了解电子料技大学有关保留、使用学位论文 瓣燕定,有粳保瞽并两困家有关部门或撬擒送交论文戆篾露箨器藤 擞允许论文被查阅和借阅。本人授权电子科技大学可以将学位论文 熟全蘸囊部分巍骞缓入有关鼗罨瘁进行检索,胃辨采露影露、缩觏裘 捆描等复制警段保存、汇编学位论文。 傈整鼢学整论文在舞密后痤遵守瑟霾定 彗名:盘垒蕴导婚签名:莶堕丛 豳期:p 7 年妒月潍日 第一章绪论 第一章绪论 本章介绍了不同的内存管理策略在j a v a 虚拟机中的应用,当前的研究现状, 方法及意义,并简要的介绍了本文提出的改进型的垃圾回收策略。最后概述了本 文的章节安排。 1 1j a v a 虚拟机简介 j a v a 技术的核心就是j a v a 虚拟机所有的j a v a 程序都在其上运行。尽管j a v a 这个名字一般用于描述j a v a 程序设计语言,但是除了语言本身以外还有很多其他 含义。j a v a 程序需要j a v a 虚拟机、j a v a a p i 和j a v ac l a s s 文件的配合,它才能够运 行起来。 多年以来,人们使用工具来完成任务,直到最近我们的工具才开始交得越来越 聪明,并且互相连接起来。微处理器已经出现在很多日常使用的物件中,并且越 来越多地和网络有了联系。举个例子,作为个人计算机和工作站的心脏,微处理 器普遍连接到了网络。微处理器也在除了p c 和工作站之外的专用设备上出现。 电视机、录像机、组合音响、传真机、扫描仪、打印机、蜂窝电话、电子记事簿、 传呼机,甚至手表都装备了微处理器,并且大多数都可以上网。再加上信息处理 能力的不断提高和费用的不断下降,网络正在迅速扩张它的触角。 逐渐通过网络连接起来的智能设备和计算机组成的基础结构开创了软件的新 环境,它为软件开发者带来新的挑战和机遇。j a v a 可以很好地帮助软件开发者面 对挑战,抓住机会,因为j a v a 是为网络而设计的。j a v a 的这种适合网络环境的能 力是由其体系结构决定的,它可以保证安全的、健壮的且和平台无关的程序通过 网络传播,在很多不同的计算机和设备上运行。 软件开发者面对的挑战之一是这种逐渐增长的以网络为核心的硬件环境,其包 含的设备越来越广泛。一般网络都有很多不同的设备、不同的硬件体系、不同的 操作系统,用于不同的用途。j a v a 通过创建与平台无关的程序来解决这个问题。 j a v a 程序可以不需要修改就在很大范围内的计算机和设备上运行。和为一个特定 的系统以及操作环境编译的程序比起来,用j a v a 编写的平台无关的程序会更容易 编写、管理和维护,代价也更低。 电子科技大学硕士学位论文 网络为软件开发者带来的另外一个挑战是安全性。除了潜在的好处,网络也为 恶意的程序员打开了渠道,他们可以窃取或者破坏信息,偷盗计算资源,或者令 人生厌地搞些恶作剧。举例来说,病毒编写者可以把他们的程序放在网络上,让 没有防护的用户下载。j a v a 解决这个挑战的方法是,提供一个受保护的环境,从 网络上下载的程序可以以不同的定制安全级别运行。 安全性的一个方面是程序的健壮性。如同恶意程序员写的狡猾的代码一样,普 意的程序员编写的有缺陷的程序也有可能破坏信息,把计算机带入死循环,或者 导致系统崩溃。 无所不在的网络带来了一个机会就是在线程序发布。j a v a 利用这个优点在网络 上传送小段的二进制代码。通过这个能力,j a v a 程序的发布会比原有的程序发布 更加方便和廉价,这也为版本控制带来了好处。因为最新版本的j a v a 程序可以在 用户需要的时候从网络上得到,所以不需要担心最终用户运行程序的版本,他们 每一次总会得到最新的版本。 平台无关性、安全性和网络移动性,j a v a 体系的这三个方面共同使得j a v a 和 发展中的网络计算环境相得益彰。因为j a v a 程序是平台无关的,可以在网络上移 动的代码和对象就更加有效可行了。同样的代码可以被送到网络所连接的所有计 算机和设备上。不同硬件平台上运行的分布式系统的各个不同组件可以互相交换 对象。j a v a 的内置安全性框架也可以帮助网络上的软件传送更加有效。因为降低 了风险,安全性框架可以使新发行的、可通过网络传输的软件是值得信任的。 j a v a 虚拟机是s u n 的j a v a 程序设计语言的基石。它是j a v a 的面向网络的核心。 它支持j a v a 面向网络体系结构三大支柱的所有方面:平台无关性、安全性和网络 移动性。j a v a 虚拟机是一个抽象的计算机,与实际的计算机一样,它具有一个指 令集并使用不同的存储器区域。 j a v a 虚拟机的主要任务是装载c l a s s 文件并且执行其中的字节码。当j a v a 虚拟 机是由主机操作系统上的软件实现的时候,j a v a 程序通过调用本地方法和主机交 互。本地方法是联系j a v a 程序和底层主机操作系统的一种途径。j a v a 虚拟机这个 中间层,屏蔽了各个主机操作系统的差异,使得j a v a 的应用程序可以经少许修改 甚至不需修改,就可以直接运行在不同的操作系统上,即平台无关性的核心就是 j a v a 虚拟机。 2 第一章绪论 1 2 内存管理策略 j a v a 显著提高开发者效率的一个重要方面就是它对直接内存操作的约束。与 c 年+ 不同,在j a v a 中,没有通过使用强制转换指针类型或者透过进行指针运算直 接访问内存的方法。在j a v a 中使用对象时,需要严格地遵守类型规则。如果存在 一个m o u n t a i n 类对象的引用,它只能作为m o u n t a i n 使用。这个引用不能强制转化 为l a v a 类型,更不能把它所指向的内存假设为一个l a v a 对象来操作。同样的, 简单地给引用加上偏移量也是被禁止的。 j a v a 避免无意间破坏内存的另一个办法就是自动垃圾收集。虽然j a v a 也和c + + 一样提供了一个n c w 操作符来进行新对象在堆中内存的分配,但它却并不提供 d e l e t e 操作符,而是会由垃圾回收线程自动回收这个废弃对象所占据的内存。 j a v a 虚拟机的垃圾回收线程,可以有多种不同的策略来进行实现。任何一种垃 圾收集算法一般要做两件基本的事情:( 1 ) 发现无用信息对象;( 2 ) 回收被无用 对象占用的内存空间,使该空间可被程序再次使用。大多数垃圾回收算法采用了 根集( r o o ts e t ) 这个概念。所谓根集,就是指正在执行的j a v a 程序可以访问的引用变 量的集合( ,包括局部变量、参数、类变量) ,程序可以使用引用变量访问对象的属性 和调用对象的方法。垃圾收集首先需要确定从根开始哪些是可达的和哪些是不可 达的,从根集开始可达的对象都是活动对象,它们不能作为垃圾被回收,这也包 括从根集开始间接可达的对象。而如果根集通过任意路径均不可达的对象,则符 合垃圾收集的条件,应该被回收。下面介绍几个常用的算法。 引用计数是一种半自动( s e m i - a n t o m a t e d ) 的内存管理技术,这表示它需要一 些编程支持,但是它不需要用户确切知道某一对象何时不再被使用。在引用计数 中,所有共享的数据结构都有一个域来保存当前活动“引用”结构的次数。当向 一个程序传递一个指向某个数据结构的指针时,该程序会将引用计数增加1 。然后, 当用户的进程完成对它的使用后,该程序就会将引用计数减少1 。结束这个动作之 后,它还会检查计数是否已经减到零。如果是,那么它将释放内存。 跟踪算法是为了解决引用计数法的问题而提出,它使用了根集的概念。基于跟 踪算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪些对象不可达, 并用某种方式标记可达对象,例如对每个可达对象设置一个或多个位。在扫描识 别过程中,基于跟踪算法的垃圾收集也称为标记和清除( m a r k a n d s w e e p ) :垃圾收集 器。 3 电子科技大学硕士学位论文 为了解决堆碎片问题,基于跟踪的垃圾回收吸收了压缩算法的思想,在清除的 过程中,算法将所有的对象移至堆的一端,堆的另一端就变成了一个相邻的空闲 内存区,收集器会对它移动的所有对象的所有引用进行更新,使得这些引用在新 的位置能识别原来的对象。在基于压缩算法的收集器的实现中,一般增加句柄和 句柄表。 复制算法的提出是为了克服跟踪算法中旬柄的开销和解决堆碎片的垃圾回收。 它开始时将堆划分为一个对象面和多个空闲面,程序从对象面为对象分配空间, 当对象面满了,基于复制算法的垃圾收集就从根集中扫描活动对象,并将每个活 动对象复制到空闲面( 使得活动对象所占的内存之间没有空闲区) ,这样空闲面变成 了对象面,原来的对象面变成了空闲面,程序会在新的对象面中分配内存。 一种典型的基于复制算法的垃圾回收是暂停复制算法,它将堆分成对象面和空 闲区域面,在对象面与空闲区域面的切换过程中,程序暂停执行。 暂停拷贝垃圾收集器的一个缺陷是收集器必须复制所有的活动对象,这增加了 程序等待时间,也是该算法低效的原因。在程序设计中有这样的规律:多数对象 存在的时间比较短,少数的对象存在时间比较长。因此,分代算法将堆分成两个 或多个,每个子堆作为对象的一代。由于多数对象存在的时间比较短,随着程序 丢弃不使用的对象,垃圾收集器将从最年轻的子堆中收集这些对象。在分代式的 垃圾收集器运行后,上次垃圾收集后存活下来的对象移到老一代的子堆中,由于 老一代的子堆不会被经常回收,因而节省了时间,降低了对应用程序运行的影响。 1 3 本文的研究工作及章节安排 1 3 1 本文研究目标 在前人已有的工作基础了,经过一年多的研究,本文将重点讨论基于j a v a 虚 拟机中的垃圾收集策略的研究,以及对其工作原理进行分析后所做的改进,在分 代式收集器的基础上,提出了一种新的内存管理算法。 j a v a 虚拟机中的内存管理,实质上是通过不同的垃圾收集策略来实现的。目前 对于虚拟机中的内存管理策略的研究,虽然提出了各种各样不同的算法,但就其 实质而言,无非两件事情。首先,它必须能够检测出垃圾对象。其次,它必须回 收垃圾对象所使用的堆空间并归还给程序。 垃圾检测通常通过建立一个根对象的集合并且检查从这些根对象开始的可达 4 第一章绪论 性来实现。如果正在执行的程序可以访问到的根对象和某个对象之间存在引用路 径,这个对象就是可达的。对于程序来说,根对象总是可以访问的从这些根对 象开始,任何可以被触及的对象都被认为是“活动”的对象。无法被触及的对象 被认为是垃圾,因为它们不再影响程序的未来执行。 本文通过对分代式垃圾收集器的研究,针对嵌入式系统所固有的特点,实时性 和无虚拟存储器,从三个方面提出了对分代收集器的改进。 在根集的确定中,通过将根集划分为对象域和局部变量域,来分别进行标记。 通过将对象域数据缩并排放,便于垃圾收集器迅速找到对象引用区。通过对字节 码的扫描,建立局部变量表,来实现对局部变量数据类型的标记。 在代的划分上,提出了动态分隔旧生代与新生代的概念。在旧生代中采用标记 清除的算法来收集,在新生代中,通过动态调整分区的大小,最大的减少活动对 象的移动,提高算法的效率。新生代中采用改进的复制算法,来实现垃圾清除。 此外,本文在研究目前已有的相关垃圾收集算法的过程中,深切的感受到算法 的提出和代码的实现存在着一定程度的脱节。笔者在这里只是提出了一个切实可 行的模块化算法,至于算法的实现,准备在部分实现的基础上,借助开源社区的 力量,让它发展壮大。 1 3 2 本文章节安排 在接下来的章节中,本文将详细讨论在实现以上研究的过程中所采用到的相关 技术以及作者所做的研究和开发工作,最后会对其发展方向做出展望,提出参考 性的建议。 第一章,绪论。主要介绍了j a v a 虚拟机技术以及垃圾收集策略的研究背景以 及研究的意义,并阐述本论文的研究内容和目标。 第二章,j a v a 虚拟机相关技术。主要说明了在本文的算法的提出过程中将会使 用的相关技术,主要是j a v a 虚拟机中的类装载器,堆和栈,以及执行引擎。 第三章,垃圾收集策略。主要介绍几种存在的垃圾收集器,并提出自己的一些 标准,对其加以衡量和评估,以便为后续章节中新算法的实现做好调研。 第四章,嵌入式上的新算法。主要介绍了一种新的基于分代式的垃圾收集器。 结合嵌入式系统的特点,建立了代的动态分割机制,以及新生代中如何进行垃圾 收集。最后结合一个例子来讨论算法存在的缺陷,并指出如何避免此类问题。 第五章,分代技术新算法的实现。主要介绍了第四章中的新算法是如何实现的。 5 电子科技大学硕士学位论文 包括对象的类图,代码的工作流程,以及一些关键代码的分析。 第六章,总结与展望。总结全文所做的工作和不足之处,提出下一步的研究方 向和开发工作。 6 第二章j a v a 虚拟机相关技术 第二章j a v a 虚拟机相关技术 j a v a 虚拟机是在所运行的目标机器之上的一个抽象层。在不同的平台上都有 j a v a 虚拟机的不同实现。但是无论是哪种平台,都可以解释执行j a v a 虚拟机指令, 因此j a v a 虚拟机是j a v a 语言实现跨平台的基础。在j a v a 平台的结构中,j v m 处 在核心的位置,它的下方是移植接口,其中依赖于平台的部分称为适配器,m 通过移植接口在具体的平台和操作系统上实现;在j 、啊江的上方是j a v a 的基本类库 和a p i ,利用j a v aa p i 编写的应用程序和小程序可以在任何j a v a 平台上运行而无 需考虑底层平台,从而实现了j a v a 的平台无关性。j a v a 程序的执行过程是:首先, 源程序( j a v a ) 经过编译器编译后生成由字节码组成的类文件( c l a s s ) ,然后由类 装载器装入来自类文件的字节码,经过检验器安全验证后,由j v m 读取字节码, 转换为特定平台的指令,并在相应的操作系统中运行。j v m 是j a v a 程序运行的心 脏,了解并分析它对于我们后面的内存管理算法的改进是非常重要的。 然而,要理解j a v a 虚拟机,我们必须首先意识到,当我们说“j a v a 虚拟机” 时,可能指的是如下三种不同的东西:抽象规范;一个具体的实现;一个运行中 的虚拟机实例。j a v a 虚拟机抽象规范仅仅是个概念,在t u nl i n d h o h n 5 和f r a n k y e l l i n n 编著的( t h ej a v av m u a lm a c h i n es p e c i f i c a t i o n ) 一书中详细地描述了它。 而该规范的具体实现,可能来自多个提供商,并存在于多个平台上。它或者完全 用软件实现,或者以硬件和软件相结合的方式来实现。当运行一个j a v a 程序的同 时,也就在运行了一个j a v a 虚拟机实例。 2 1j a v a 虚拟机的生命周期 一个运行时的j a v a 虚拟机实例的天职就是:负责运行一个j a v a 程序。当启动 一个j a v a 程序时,一个虚拟机实例也就诞生了。当该程序运行结束退出,这个虚 拟机实例也就随之消亡。如果在同一台计算机上同时运行三个j a v a 程序,将得到 三个j a v a 虚拟机实例。每个j a v a 程序都运行于它自己的j a v a 虚拟机实例中。 j a v a 虚拟机实例通过调用某个初始类的m a i n o 方法来运行一个j a v a 程序。而 这个m a i n 0 方法必须是公有的( p u b u c ) 、静态的( s t a t i c ) ,返回值为v o i d ,并且接受一 个字符数组作为参数。任何拥有这样一个m a i n o 方法的类都可以作为j a v a 程序运 7 电子科技大学硕士学位论文 行的起点。 比如,对于图2 - 1 这样一个j a v a 程序,它打印出传给它的命令行参数: c l a s s e c h o ( p u b l i cs t a t i cv o i dm a i n ( s u n g f la r g v ) i n tl e n = a r g v 1 e n g t h ; f o r ( i n t i = o ;i 一个指向方法区对应类数据的指针 此对象的方法表 方法表是一个指针数组,其中的每一项都是一个指向“实例方法数据”的指针。 实例方法可以被该类的对象调用,方法表指向的实例方法数据包括如下信息: 此方法的操作数栈和局部变量区的大小 此方法的字节码 异常表 这些信息足够虚拟机去调用一个方法了,方法表中包含有方法指针指向类 或其超类声明的方法的数据。也就是说,方法表所指向的方法可能是此类声明的, 也可能是它继承下来的。 图2 - 6 保持方法区数据随时可用 如果大家熟悉c + + 的内部机制,就会发现这和c + + 的v t b l ( c + + 对象的虚拟表) 非常相似。在c + + 中,对象由实例数据和一组指向对象可以调用的虚拟函数的指针 组成。j a v a 虚拟机也可以采用这种方法,虚拟机可以在堆中为每个对象都附加一 第二章j a v a 虚拟机相关技术 个方法表,这样较之图2 _ 6 的方法会占用更多的内存,但可以轻微的提高一些效 率。一般来说,该方案只适用于内存足够充裕的系统 图2 - 4 和2 - 5 中显示的还有另一种数据,堆上的对象数据中还有一个逻辑部分, 那就是对象锁,这是一个互斥对象。虚拟机中的每个对象都有一个对象锁,它被 用于协调多个线程访问同一个对象时的同步。在任何时刻,只能有一个线程“拥 有”这个对象锁,因此只有这个线程才能访问该对象的数据。此时其它希望访问 这个对象的线程只能等待,直到拥有对象锁的线程释放锁当某个线程拥有一个 对象锁以后,可以继续对这个锁追加请求。但请求几次,必须相应的释放几次, 之后才能轮到其他线程。比如一个线程请求了三次锁,在它释放三次锁之前,它 一直保持“拥有”这个锁。 很多对象在其整个生命周期内都没有被任何线程加锁。在线程实际请求某个对 象的锁之前,实现对象锁所需要的数据是不必要的。许多实现不在对象自身内部 保存一个指向锁数据的指针,而只有当第一次需要加锁的时候才分配对应的锁数 据,但这时虚拟机需要用某种间接方法来联系对象数据和对应的锁数据,例如把 锁数据放在一个以对象地址为索引的搜索树中。 除了实现锁所需要的数据外,每个j a v a 对象逻辑上还与实现等待集合的数据 相关联。锁是用来实现多个线程对共享数据的互斥访问的,而等待集合是用来让 多个线程为完成一个共同目标而协同工作的。 等待集合由等待方法和通知方法联合使用。每个类都从o b j e c t 那里继承了三 个等待方法( 三个名为w a i l 0 的重载方法) 和两个通知方法( n o t i f y 0 以及 n o t i f y a l l0 ) 。当某个线程在一个对象上调用等待方法时,虚拟机就阻塞这个线 程,并把它放在了这个对象的等待集合中。直到另一个线程在同一个对象上调用 通知方法,虚拟机才会在之后的某个时刻唤醒一个或多个在等待集合中被阻塞的 线程。正像锁数据一样,在实际调用对象的等待方法或通知方法之前,实现对象 的等待集合的数据并不是必需的。因此,许多虚拟机实现都把等待集合数据与实 际对象数据分开,只有在需要时才为此对象创建同步数据( 通常是在第一次调用 等待方法或通知方法时) 。 最后一种数据类型可以作为堆中某个对象映象的一部分,是与垃圾收集器 有关的数据。垃圾收集器必须( 以某种方式) 跟踪程序引用的每个对象,这个任 务不可避免地要附加一些数据给这些对象,数据的类型要视垃圾收集使用的算法 而定。例如,垃圾收集器使用“标记并清除”算法,这就需要能够标记对象是否 被引用。此外,对于不再被引用的对象,还需要指明它的终结方法是否已经被运 1 7 电子科技大学硕士学位论文 行过了。像线程锁一样,这些数据也可以放在对象数据外。有一些垃圾收集技术 只在垃圾收集器运行时需要额外数据。例如“标记并清除”算法就使用一个独立 的位图来标记对象的引用情况。 除了标记对象的引用情况外,垃圾收集器还要区分对象是否调用了终结方法。 对于在其类中声明了终结方法的对象,在回收它之前,垃圾收集器必须调用它的 终结方法。j a v a 语言规范指出,垃圾收集器对每个对象只能调用一次终结方法, 但是允许终结方法复活这个对象,即允许该对象被再次引用。这样当这个对象再 次被回收时,就不用再调用终结方法了需要终结方法的对象不多,而需要复活 的更少,所以对一个对象回收两次的情况很少见。这种用来标志终结方法的数据 虽然逻辑上是对象的一部分,但通常实现上不随对象保存在堆中。大部分情况下, 垃圾收集器会在一个单独的空间保存这个信息。 2 2 3 栈 每当启动一个新线程时,j a v a 虚拟机都会为它分配一个j a v a 栈。j a v a 栈等价 于传统语言例如c 语言的栈:它保存局部变量和部分中间结果,并参与方法的调 用和返回。j a v a 栈以帧为单位保存线程的运行状态。虚拟机只会直接对j a v a 栈执 行两种操作:以帧为单位的压栈或者出栈。 某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧成为 当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。在线 程执行一个方法时,它会跟踪当前类和当前常量池。此外,当虚拟机遇到栈内操 作指令时,它对当前帧内数据执行操作。 每当线程调用个j a v a 方法时,虚拟机都会在该线程的一个j a v a 栈中压入一 个新帧。而这个新帧自然就成为了当前帧。在执行这个方法时,它使用这个帧来 存储参数、局部变量、中间运算结果等等数据。 j a v a 方法可以以两种方式完成。一种通过r e t u r n 返回的,称为正常返回;一 种是通过抛出异常而异常中止的。不管以哪种方式返回,虚拟机都会将当前帧弹 出j a v a 栈然后释放掉,这样上一个方法的帧就成为当前帧了。 j a v a 栈上的所有数据都是此线程私有的。任何线程都不能访问另一个线程的 栈数据,因此我们不需要考虑多线程情况的栈数据的访问同步问题。当一个线程 调用一个方法时,方法的局部变量保存在调用线程j a v a 栈的帧中。只有一个线程 能够总是访问那些局部变量,即调用方法的线程。 第二章j a v a 虚拟机相关技术 像堆一样,j a v a 栈和帧在内存中也不必是连续的。帧可以分布在连续的栈里, 也可以分布在堆里,或者两者兼而有之。表示j a v a 栈和栈帧的实际数据结构由虚 拟机的实现者决定,某些实现允许用户指定j a v a 栈的初始大小和最大最小值。 j a v a 虚拟机的栈帧用于存储一个方法的数据和部分中间结果,以及进行动态 链接,获得方法的返回值和异常处理。 当一个j a v a 方法被调用时都会创建一个新的栈帧,当方法结束时,不论是正 常的还是不正常的( 抛出异常结束) 返回,当前栈帧都要被撤销。栈帧从创建该 栈帧的线程的j a v a 栈中分配。每个栈帧都有它自己的局部变量和自己的操作数栈, 这些结构的存储空间可以同时分配,因为编译器可以在编译期间获得局部变量区 和操作数栈的大小,因此方法在运行时占用的最大空间也可以确定。 在一个给定线程的任何时刻,只有一个栈帧,也就是正在执行的方法的栈帧是 活跃的。这个栈帧称为当前栈帧,它的方法称为当前方法,定义这个方法的类为 当前类,局部变量和操作数栈上的操作都是作用于当前栈帧的。 当前栈帧的方法调用另一个方法或者这个方法结束,则栈帧不再是当前的,调 用的这个方法会创建一个新的栈帧并成为当前栈帧。当方法返回时,如果方法有 返回值,则当前栈帧把返回值传递给上一栈帧,然后当前栈帧被抛弃,上一栈帧 成为当前栈帧。栈帧一般从每个线程的栈上分配的,也可以从j a v a 虚拟机的堆中 分配。 栈帧由三部分组成:局部变量区,操作数栈和帧数据区。局部变量区和操作数 栈的大小要视对应的方法而定,它们是按字长计算的。编译器在编译时就确定了 这些值并放在c l a s s 文件中。而帧数据区的大小依赖于具体的实现。 当虚拟机调用一个j a v a 方法时,它从对应类的类型信息中得到此方法的局部 变量区和操作数栈的大小,并据此分配栈帧内存,然后压入j a v a 栈中。 局部变量区被组织为一个以字长为单位、从0 开始计数的数组。字节码指令通 过从0 开始的索引来使用其中的数据。类型为i n t ,f l o a t ,r e f e r e n c e 和 r e t u r n a d d r e s s 的值在数组中只占据一项,而类型为b y t e ,s h o r t 和c h a r 的值在 存入数组前都将被转换为i n t 值,因而同样占据一项。但是类型为l o n g 和d o u b l e 的值在数组中却占据连续的两项。 在访问局部变量中的i o n g 和d o u b l e 值的时候,指令只需指出连续两项中第一 项的索引值。例如某个l o n g 值占据第三四项,那么指令会取索引为3 的l o n g 值。 局部变量区的所有值都是字对齐的,l o n g 和d o u b l e 这样占据两项数据元素的值同 样可以起始于任何索引。 电子科技大学硕士学位论文 和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。但是和 前者不同的是,它不是通过索引来访问,而是通过标准的栈操作压栈和出栈 来访问的。比如,如果某个指令把一个值压入到操作数栈中,稍后另一个指 令就可以弹出这个值来使用。 虚拟机在操作数栈中存储数据的方式和在局部变量区中是一样的,如i n t 、 l o n g 、f l o a t 、d o u b l e 、r e f e r e n c e 和r e t u r n t y p e 的存储。对于b y t e ,s h o r t 以及 c h a r 类型的值在压入到操作数栈之前,也会被转换为i n t 。 不同于程序计数器,j a v a 虚拟机没有寄存器,程序计数器也无法被程序指令 直接访问。j a v a 虚拟机的指令是从操作数栈中而不是从寄存器中取得操作数的, 因此它的运行方式是基于栈的而不是基于寄存器的。虽然指令也可以从其他地方 取得操作数,比如从字节码流中跟随在操作码( 代表指令的字节) 之后的字节中 或从常量池中,但是主要还是从操作数栈中获得操作数。 虚拟机把操作数栈作为它的工作区大多数指令都要从这里弹出数据,执行 运算,然后把结果压回操作数栈。比如,i a d d 指令就要从操作数栈中弹出两个整 数,执行加法运算,其结果又压回到操作数栈中。如下例所示: i l o a d _ _ op u s ht h ei n ti nl o c a lv a r i a b l e0 i l o a d _ lp u s ht h eh a ti nl o c a lv a r i a b l e1 i a d d p o pt w oi a t s ,a d dt h e m , p u s hr e s u l t i s t o r e _ 2 p o pi n ls t o r ei n t ol o c a lv a r i a b l e2 在这个字节码序列里,前两个指令i l o a d _ o 和i l o a d _ l 将存储在局部变量区索 引为0 和1 的整数压入操作数栈中,其后i a d d 指令从操作数栈中弹出这两个整数 相加,再将结果压入操作数栈。第四条指令i s t o r e _ 2 则从操作数栈中弹出结果, 并把它存储到局部变量区索引为2 的位置。图2 - 7 详细描述了这个过程中局部变 量和操作数栈的状态变化,图中未使用的局部变量区和操作数栈区域以空白表示。 o a d0l l o a dii a d di s t o m2 开始之前 指令:启指令乏后指令之后指令2 狺 局部变量 ! 目! 目霄雹! 目 操作数栈e 三三三 e 翌e 丑e 当e 三三三 图2 - 7 两个局部变量的相加过程 除了局部变量区和操作数栈外,j a v a 栈帧还需要一些数据来支持常量池解析、 正常方法返回以及异常派发机制。这些消息都被保存在j a v a 栈帧的帧数据区中。 2 0 第二搴j a v a 囊擞壤稳关援寒 j a v a 虚拟机中的大多数指令都涉及到常量池入口。肖些指令仅仅是从常量池 中取出数据然后臁入j a v a 栈( 这些数据的类型包括i n t 、l o n g 、f l o a t 、d o u b l e 纛s t r i n g ) ;还露整摇令爱躅鬻塞漶瓣数攥寒摇忝要实援缘瓣类或数缎、要谚楚熬 字段,或要调用的方法;还肖魑指令需要常量池中的数据才能确定莱个对象是否 属于某个类或者实现了某个接口 每当虚拟机簧执雩亍某个嚣黉用到鬻量漕数据静指令对,它都会透过羧数据区中 籀囱常差灌翦搔镑来访褥它。除7 焉予常爨泡的解析井,鲮数据区还簧帮助虚攘 机娥理j a v a 方法的正常结柬溅异常中止。如果是通过r e t u r n 正常结束,虚拟机 必须恢复发起调用的方法的栈帧,包括设鹫p c 寄存器指f 翘发起调用的方法中的指 令一帮紧壤罄诞雳7 完戏穷法戆指令豹节一令缮令。羧蘩方法客运溷篷,虚援 机必须将它压入列发起调用的方法的操作数栈。 为了处理j a v a 方法执行期间的异常退出情况,帧数据区还必须保存一个对此 方法异常表豹引耀。当某个方淡抛出异常孵,瘟拟机根壤姣数据区对暾戆异常表 来决定鲡俺赴瑗。如果在异鬻袭中我鹫了嚣鼯静c a t c h 予旬,就会辩控制权转交 给c a t c h 子旬内的代码。如果没有发现,方法会立即异常中止。然后康拟机使用 帧数据区的信息恢复发起调用的方法的帧,然后在发起调用的方法的上下文中重 裁搬雍霹群貔舅黉。 2 2 4 执行弓l 擎 运行中j a v a 程序静每一令线程都是一个独立的虚羧秘捷行辱l 擎鹃蜜铆。葳线 程缴命周期的开始到结束,它舞么是在执杼字节码,要么在执行本地方法。一个 线瑕可能通过解释或者使用旗片集指令直接执行字节码,或者间接通过即时编译 爨羧学绽泽蓬戆零建筏磅。j a v a 霪菝援熬爽嚣莓麓霉一黧鼹震声程彦琴霉霓豹线 程,比如垃圾l i 叟集器。这样的线程不需要怒实现的执行碍i 擎的实例。所有属于用 户遴行程序的线程,都是在实际工作的执行引擎。 方法豹字节弼滚是j a v a 纛羧辊豹指令膨剽构成豹,每一条指令瓴禽个单字 节豹操作码,屠瑟跟随0 个躐多个操作数。操作数表明黉执行的揉俸;操作数向 j a v a 虚拟机提供执行操作码需要的额外信息。操作码本身就已经规定了它是否需 要跟随操作数,以及如果有搽俸数的话,它是什么形式的。很多j a v a 虚拟机的指 令不包含搽终数,仅仅是圭一今操捧羁字麓褥成戆。裰糖漾终褥煞霭簧,纛攘税 可能除了跟随操作码的操作数乏外,还需要从另外一些存储区域得到操作数。当 电子科技大学硕士学位论文 虚拟机执行一条指令的时候,可能使用当前常量池中的项、当前帧的局部变量中 的值,或者位于当前帧操作数栈顶端的值。 抽象的执行引擎每次执行一条字节码指令。j a v a 虚拟机中运行的程序的每个线 程( 执行引擎实例) 都执行这个操作。执行引擎取得操作码,如果操作码有操作 数,取得它的操作数。它执行操作码和跟随地操作数规定的动作,然后再取得下 一个操作码。这个执行字节码的过程在线程完成前将一直持续,通过从它的初始 方法返回,或者没有捕获抛出的异常都可以标志着线程的完成。 执行引擎会时不时的遇到请求本地方法调用的指令。在这个时候,虚拟机负责 试着发起这个本地方法调用。如果本地方法返回了( 假设是正常返回,而不是抛 出了一个异常) ,执行引擎会继续执行字节码流中的下一条指令。 平台无关性是影响指令集设计的最大因素。指令集的这种以栈为中心、而非以 寄存器为中心的设计方法,使得在那些只有很少的寄存器,或者寄存器很没有规 律的机器上实现j a v a 更便利。j a v a 以栈为中心设计指令集的另一个原因是,编译 器一般采用以栈为基础的结构向连接器或者优化器传递编译的中间结果。对于j a v a 来说,虚拟杌是作为( 动态) 连接器使用的,也可以作为优化器。在j a v a 虚拟机 指令集设计中,以栈为中心的体系结构可以将运行时进行的优化工作与执行即时 编译或者自适应优化的执行引擎结合起来。 影响指令集设计的另一个目标就是进行字节码校验的能力,特别是使用数据流 分析器进行的一次性验证。j a v a 的安全框架需要这种验证能力。在装载字节码的 时候使用数据流分析器进行一次性验证,而非在执行每条指令的时候进行验证, 这样做有助于提高执行速度。在指令集中体现这个目标的表现之一,就是绝大部 分操作码都指明了它们需要操作的类型。 字节码的执行技术的实现可以有很多种选择:解释、即时编译、自适应优化、 芯片级直接执行。关于执行技术,最重要的一点就是,实现可以自由选择任何技 术来执行字节码,只要它遵守j a v a 虚拟机指令集的定义。 最有意义也是最迅速的执行技术之一就是自适应优化。自适应优化已经在几种 现有的j a v a 虚拟机实现中使用了,如s u n 的h o t s p o t 虚拟机。它们都从早期虚拟 机实现所使用的技术中得到了很多的借鉴。最初的虚拟机每次解释一条字节码; 第二代虚拟机加入了即时编译器,在第一次执行方法的时候先编译成本地代码, 然后执行这段本地代码。也就是说,不管什么时候调用方法,总是执行本地代码。 自适应优化器搜索那些只有运行时才有效的信息,试图以某种方式把字节码解释 和编译成本地代码结合起来,以得到最优化的性能。 第二章j a v a 虚拟机相关技术 自适应优化的虚拟机开始的时候对所有的代码都是解释执行,但是它会监视代 码的执行情况。大多数程序花费8 0 9 0 的时间来执行1 0 2 0 的代码。因 为可以监视程序的执行情况,所以虚拟机可以意识到哪些方法是程序的“热区” 就是那1 0 2 0 的代码,它们占整个执行时间的8 0 9 0 。 当自适应优化的虚拟机判断出某个特定的方法是瓶颈的时候,它启动一个后台 线程,把字节码编译成本地代码,非常仔细地优化这些本地代码。同时,程序仍 然通过解释来执行字节码。因为程序没有中途挂起,并且只编译和优化那些“热 区”( 大约1 0 2 0 的代码) ,虚拟机可以比传统的即时编译更注重优化性能。 自适应优化技术使程序最终能把原来占8 0 9 0 运行时间的代码交为极度 优化的、静态连接的c + + 本地代码,而使用的总内存数并不比全部解释j a v a 程序 大多少。换句话说,就是执行速度更快了。自适应优化的虚拟机可以保留原来的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全培训教师岗位证书课件
- 2025年榆林华源电力有限责任公司招聘(5人)模拟试卷及完整答案详解1套
- 2025春季中国电信实习生招聘模拟试卷含答案详解
- 2025年安徽皖信人力资源管理铜陵分公司招聘20人模拟试卷含答案详解
- 2025内蒙古鄂尔多斯市康巴什区青年就业见习计划招募模拟试卷及答案详解(名师系列)
- 2025国家农业农村部食物与营养发展研究所综合办公室助理招聘4人模拟试卷及答案详解(必刷)
- 小学劳动安全培训制度课件
- 2025河北邯郸冀南新区选聘农村党务(村务)工作者111人考前自测高频考点模拟试题及完整答案详解
- 2025年PCB制板项目合作计划书
- 2025年上海市金融稳定发展研究中心公开招聘工作人员考前自测高频考点模拟试题及1套完整答案详解
- 保险的销售合同(标准版)
- 电子元器件仓库管理规范
- 房屋安全知识培训资料课件
- 2025年第十七届广东省中学生天文知识竞赛试题(含答案)
- 小学生新能源汽车
- 2025年职业病诊断医师资格考试(职业性化学中毒)历年参考题库含答案详解(5卷)
- 2025年仓库保管工技师考试题库
- 肥胖患者体重管理护理查房
- (新教材)2025年秋期人教版一年级上册数学全册核心素养教案(教学反思无内容+二次备课版)
- 2025年音乐新课标试题及答案
- 黑龙江省合格考数学试卷
评论
0/150
提交评论