免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1417 | 回复: 0
打印 上一主题 下一主题

[转]PhoneMe Advanced 浅度探索 七 ----JAVA平台的多任务:什么是大交易? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-11 00:57 |只看该作者 |倒序浏览

Mark Lam has been a virtual machine engineer in the JavaME CDC team at Sun Microsystems for over 6 years. Before joining Sun, he was a real-time embedded systems developer for 6+ years, working on application frameworks, graphics systems, networking protocols, game development, and fault tolerant systems amongst other things, on devices ranging from 64KB 8bit uControllers to 32-bit RISC machines.
原文URL:
http://weblogs.java.net/blog/mlam/archive/2006/11/multitasking_th_1.html


         今天,我在java.net论坛看到了这个
讨论
。它让我感到惊奇,假如所有人都意味着同一个事情,如果当他们在谈论java平台的多任务时。因此,我决定今天暂停讨论CVM,开始多任务(这也与phoneME和CVM相关)

不承诺:在开始前,我必须阐明我的观点只代表我个人,不代表Sun,我的雇主,我在Sun的同事。
什么是多任务?
       严格的说,多任务意味着同一时间能做多个事情。对JAVA平台,这意味着能够有同时执行的代码。JAVA平台已经支持多任务。因此,这个问题是什么?人们想同时更好的运行多个程序。这到底和从不同的线程调用程序的main()函数有什么不同?不同是,程序想要自己的世界和所有的资源。简单的运行它们在不同的线程可能只有边缘效果,当一个程序能同其他操作交互的时候。因此,一个多任务JAVA平台需要能够分别隔离那些程序。那么,我在那里听到的这些特性点和行为?为什么这是现在操作系统的普遍应用。
       因此,当人们想要多任务的时候,我想他们是想要求一个JAVA进程,JAVA平台代替这些系统相关的角色。让我们看看多任务特点在系统中,看看这些在JAVA平台下证明了什么。我们应该关心人们想要的这些特点。让我们先从系统开始。。。
系统透视
       如果我们为JAVA平台处理,他们应该有下面的特点:
特点                            JAVA平台包含
同时(Concurrency)        多程序能同一时间运行在同一设备上。系统能够
                  保证程序间资源的合理分配
隔离(Isolation)          每个程序必须有自己的VM环境。一个程序不能同
                  其他同时运行的程序冲突。在错误的程序环境中,              
                  错误和不良行为能被检测
可靠的终止(Reliable Termination)  当程序出错,程序管理器必须能够中止程序并可靠
                  的回收资源
效率(Efficiency)          减少资源使用的冗余,在程序间最大限度的共享
                  资源。在JAVA VM对每个程序初始化的时候减
                  少冗余
JSR 121 Application Isolation API 定义了API来管理这些特点。同隔离成为系统处理。无论如何,有API并不是就有了执行。
人们想要什么
       这儿有一些解释关于人们为什么想要多任务。这些例子不一定能详细,但我想它们很现实,能够马上解决这个问题。
问题1:你工作在一个运行不支持进程简单嵌入式系统的设备,你不能提供系统升级因为所有的本地代码你都已经投资。升级意味着移植所有的原始代码到新的系统,这非常昂贵。你已经为所有的系统代码的许可付了钱。但是你想同时在设备上运行多个程序,程序由你不能控制的第三方提供。用户甚至需要运行一些从网络上下载的程序。不幸的,如果你的设备crash或者开始运行缓慢,你的用户将责备你而不是程序,尽管他10岁的儿子是从不安全的站点下载的程序。
       那么,你考虑。。。JAVA平台是一个虚拟运行环境,为什么你不仅仅让它保持,当程序要向其他程序或系统做坏事的时候?问题解决!
问题2:你写了一个浏览程序,需要运行JAVA程序作为插件。当你不需要它时,你可以让它到一边去而不消耗资源。你想JAVA VM提供这些。但现在,你的系统本地API不能给你一个方便的方法让你做这个。自从JAVA VM被作为一个库被装载来匹配你的浏览程序。如果你使用系统特性来赶走VM,你将结束你的浏览程序,或者让它僵死而挂起。这会让你看到不好的东西。
       那么,你考虑。。。JAVA VM是一个装载程序的东西,对吗?为什么你不把程序结束并让它自己清理干净?问题解决。
问题3:你需要同时在你的设备上运行多个java程序,但系统不让java程序共享资源。。。或者资源不够。
       你考虑。。。不少所有的java程序都需要同一个class libraries来运行?为什么JAVA VM不让他们共享内存中的同一副本?问题解决!
不够快
考虑这些。。。
       对问题1,为什么执行器不考虑执行隔离在它自己的程序里,或者改善嵌入系统来做这些?毕竟JAVA VM也是软件的一块,它也从它的程序里被启动。如果它能够改善它的系统隔离能力,那每一个启动的JAVA VM都能有它自己的进程,它的问题就会被解决。
       对问题2,为什么执行器不考虑执行,在浏览程序里,一个资源跟踪系统捕获所有被JAVA VM使用的资源和正在运行的程序?如果浏览器能跟踪所有它的资源,那么它能杀死VM和程序线程,收回所有它自己的资源。
       对问题3,为什么执行器不试着改善系统(或者询问系统提供商)来多更好的工作在共享普通资源?
       对所有3个问题的答案:这是很困难的。。。非常困难。转移这些问题到JAVA平台不会让它变容易。现在好了,这儿有几个信息,JAVA VM有可能很高机会完成这个目标。但本质上,这个问题没有变容易。
       我只想让你考虑这个问题的复杂性。当你自己解决了一个问题,你的感谢为它改变。多任务不是一个价值不高的特性,Sun或其他JAVA平台提供商能够发出其他弹点在他们的成品线路图。执行多任务是一个主要承诺
       Sun已经发出了2个多任务虚拟机解决方案对CLDC和CDC,让我们看看它们怎么工作?
引擎盖下是什么?
       上面3个举例的每一个是多任务的3个不同的需要:隔离(isolation)、可靠的终止(reliable termination)、效率(efficiency)。在现实生活中,这些特性的几个或全部都需要集中在一起。
       我不会同时谈论这些特性,因为它们不是解决方案的难点。JAVA平台已经支持同时执行线程。它不是太多延伸对建立程序并发。除非你需要一些特殊的进程安排道具,我会离开这个讨论。
隔离(isolation)
       CLDC不支持一个本地接口对本地方法。在实践中,大多数的CLDC程序是MIDlets,它是100%的纯java代码。因此,CLDC MVM只需要处理java state和java bugs的隔离
       在java state方面,我的意思是类静态域(class static fields),一个实例被系统库使用。系统库被所有的程序使用。不需要隔离,每个程序都能够在系统库里看到其他程序的操作。
       一个java bug的例子是僵死状态。一个程序有2个线程同步操作2个不同的对象在对立面。结果,每个线程将会锁住来等待另外的线程来释放其它的锁定,每个线程将永远锁定来等待其它线程。无隔离,其它程序线程可能会同步同一个对象并永久的锁住。因此,一个行为不好的程序问题会导致其它行为良好的程序。
CLDC隔离
       CLDC MVM的解决方法是复制(replicating)所有静态域在系统库中。每个隔离得到它自己的一份拷贝。结果,类/静态初始化需要对每个隔离运行一次,来保证静态拷贝的初始化是隔离的。在这个机制下,每个隔离会创建它们自己单一对象的拷贝在系统中。
    CLDC隔离同样涉及一些小把戏来确保不同的程序得到不同的锁定实例当同步在ROMized 类和字符串实例这些不能在 JAVA VM中复制的。实际字符串(interned strings)被同样的对待。
    拥有java 状态自动隔离结果在java bugs的隔离中。如果一个程序僵死,其他程序不会受到影响因为僵死程序的java state对它们不可见。
    这儿有另外一种java bug:恶意程序有目的的做一些拒绝服务(DoS)攻击对其他程序。一个例子是消耗完所有可用内存让其他程序不能运行。CLDC MVM依靠每个隔离实行资源配给来解决这个问题。如果一个隔离试图获得额外的资源,它会得到一个内存不够(OutOfMemoryError)的错误,而其他程序仍可以分配内存 。
CDC隔离
       CDC需要为本地方法支持java本地接口(JNI)。因此,CDC VM需要为每个本地状态或错误提供隔离。本地状态,我的意思是本地代码的全局和静态变量。本地错误包括那些残留在内存中的废指针,分裂的块(segmentation faults),非法的指令等等。
    掌握这些是在系统进程中隔离本地代码的唯一出路。。。对每一个程序。CDC VM做这些是完全正确的。它使用特殊的处理类型叉子(fork)来生产新的隔离。每个隔离运行在它们自己的进程中。CDC MVM当前仅仅在linux和solaris下可用,因为这有这些系统提供叉子(fork)兼容。Java级的隔离是进程自动掌握的。
    象DoS攻击应付资源缺乏,CDC VM应用系统去执行配额假如需要。这没有什么不同和本地程序对应资源缺乏的解决方法来说。
可靠的终止
CLDC 隔离终止
       CLDC MVM提供自己的线程库。当它需要终止程序时,它简单的选择不计划更多的程序,并取消所有的参考来隔离。因为所有的程序都是100%的纯java代码,它们的资源会通过垃圾回收(garbage collector)来清空。一些资源有本地副本,这些会被那些由GC触发的私有终结器(finalizers)来清空。注意:终结器不是CLDC规格的一部分。它是一个VM提供的一个被系统库使用的执行。
CDC 隔离终止
       CDC MVM里的隔离有自己的进程,终止是简单的杀死各自的进程。
效率
CLDC 普通资源共享
    CLDC MVM,所有的隔离作为线程运行在同一个物理VM,它们自动共享所有常量数据。这包括类的元数据(metadata)(比如常量池,属性),method bytecodes,ROMized对象和内部字符串。
    每个隔离从java堆中得到一个配额。通常,从java堆中分配的资源不是共享的。无路如何,这儿有更少的内部破碎因为分配的隔离来自同一个堆。
    开始一个新的隔离不需要VM完全重初始化。无论如何,系统库的类初始化需要重运行。
CDC 普通资源共享
       CDC MVM,隔离是从一个共同的进程分离(fork)出来的不同的进程,它们共享作为数据的只读内存页,不需要写入。CDC MVM采用几种技术来帮助系统最大化共享。
    在CDC MVM开始一个新隔离也不需要child VM完全重新初始化,但工作线程需要重生因为进程分离(fork)不和线程工作。象CLDC,类的初始化也需要重运行。
CDC MVM是真的MVM?
       如果CDC MVM应用它的很多特性在系统进程,它和其他简单运行完整CDC VM的不同实例在进程中有什么不同?MVM被优化来允许有效的资源共享,但单个完整的VM做不到。这些优化也导致了一些性能上的开销但不会在单个完整VM上。什么?MVM有性能开销?为什么?是的,你想它会免费?你在2个隔离之间共享更多,开销也会更多。反过来也一样。但通常开销只有2~3%(如果我记得正确)。这可能或不可能成为你需要性能上的重要依靠。
       MVM和程序管理器一起来管理隔离,和单个完整VM运行在不同进程不一样,你有你自己的进程。
       在练习中,不是所有的隔离完全可用因为系统进程也会使用。比如,一些物理资源(硬件和系统)不能复制。因此,访问这些资源需要在隔离之间协调以至于它们不能相互一起。一个例子是绘画屏。Java类库(或他们的本地代码)需要修改来允许隔离间的协调。这个协调有程序管理器控制。
       物理资源的协调由CLDC MVM来执行。
我能在CDC中使用CLDC风格的MVM吗?
       技术上可以。。。但是这儿有个问题。CLDC风格的MVM不能做关于本地代码隔离的事情。那么,让我们看看我们只需要在环境中配置VM在我们保证那儿没有本地代码在程序中(或者我们拒绝有本地状态的程序)。那么我们能使用CLDC风格的MVM了吗?
       是的,但这儿仍然充满了附加的挑战。CDC的VM(CVM)运行在完全pre-emptive的本地线程上。调度程序在系统中,不是VM。因此,VM在线程调度上没有控制权(如果系统不提供这个机制。。。通常,他们不提供)。因此,近似于CLDC不能进行可靠的终止工作。
       我们还记得老的Thread.stop()API。但我们已经知道它有一个
问题
。但是,我们在这儿谈论的是100%的纯java代码程序。我们说我们不会让任何的本地代码运行。我们有CLDC风格的MVM来隔离java状态。这会让Thread.stop()的问题走开吗?现在让我们的任务终止?

       是的,我们可以让它工作。VM可以设置一个标志来在隔离中指出一个终止状态来终止。检查这个终止状态需要插入一系列的地方:VM Interpreter,JIT编译器生产的编译后代码,本地代码中的循环。这些保证线程被终止
       在这些检查点,如果终止状态被检测到,一个未捕获的异常将被抛出。VM会忽略try-catch块当它出来这个异常。这确保程序不能捕获异常并防碍线程被终止。异常会导致java和本地堆栈展开。
       VM能够展开堆栈框架为java bytecode methods。但本地方法会要求本地方法检测异常并返回。因此我们不允许任何程序的本地代码,我们只在系统库中处理本地代码。每个本地方法会被修改来检测终止状态,确保它作为异常的替代返回
       另外,所有本地方法需要被检查以确保他们释放了所有的由他们方法中分配的资源。这些资源必须被清空在方法返回异常堆栈展开前。一些本地资源没有被分配和使用在一些本地方法。对这些类型的资源,我们需要确保他们同finalizer java对象的关联,因此他们能被取回当对应的java对象被GC时。
为什么我不能有自己的CLDC风格的MVM在CDC?
       你是不是感到疲惫?我们需要做这么多步骤为了在CDC中执行CLDC风格的MVM无疑是冗长的。现在考虑CDC库同CLDC库的复杂度和大小。因为所有本地库将被适当的修改来迎合CLDC风格的MVM正确的工作。这个执行努力是相当的高。风险也相当的高。
       另外,如果VM部署在一些中间设备堆(例如对机定盒的MHP中间设备),所有这些中间设备的本地代码也需要同样的处理来保证CLDC风格的MVM正确工作。
       因此,这个风格的MVM对CDC来说执行难度是相当的高。Sun究竟有没有试验代码在CVM上来执行这种MMV。因为执行的花费和风险包含本地代码部分,这些代码从来没被完成。但是,它和快会被开原在下一个phoneMe Advanced版本,欢迎每一个感兴趣的人来完善它。
JavaSE的MVM?
       CDC风格的MVM可能或不可能在JavaSE中运用。这些VM的结构不同。但是,他们可能或不可能有利于这个途径。JavaSE VM的类共享特性已经是这个方向的一步了。
       CLDC风格的MVM。如果你明白它同CDC的不同,你可以看到它已经很大程度上接近JavaSE了。这是因为JavaSE有相当大的类库。但是,只有这些库中的本地代码会被贡献不同。幸好,JavaSE库的大部分是纯java代码,但这足够让这个任务较少的让人畏惧。
如果我不需要所有的隔离特性?
       CDC,你已经有命名空间隔离通过使用类装载器(classloader)。这儿有部署在基于同步线程和类装载器命名空间隔离的系统。但是,这些系统经受不同的缺点来自真隔离的。一个通常的抱怨是一个行为不当的程序能够坠毁整个系统,所有的程序都同它一起坠毁。
       已经有厂商提供MVM解决方案。我总是希望他们能做一些工作象Sun在分析问题,或者他们提供一部分的解决方案。但是我没有使用他们的VM,我不知道他们的MVM是怎样完成的。
这对你意味着什么?
我希望你现在理解这个令人畏惧的任务包含在建立MVM解决方案中。我明白当你需要MVM的时候它还不可用,知道去执行这个这是很困难的。
但是,现在java平台开源了,如果这些特性对你来说非常重要,请贡献在VM领域。如果我们为这个工作在一起一点时间,我们能让MVM更快实现。
祝有美好的一天!


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/85193/showart_1823109.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP