Java共享类 - 编程入门网
Java共享类时间:2011-02-28 IBM Lakshmi Shankar要真正彼此隔离 Java 应用程序,实质上需要多个 JVM,然而启动成本和内存占用使这种方式不那么理想。而共享类可以同时解决这两个问题。在多 JVM 环境中,共享类通过将一组核心系统类装载到共享内存中,可以在多个 JVM 中共享这些类。这些共享类放到内存的一个共享区域中,它们在这里对所有 JVM 都是保持一致的。结果,共享类只需要在第一次使用时装载到内存中,这消除了在以后每次 JVM 调用时装载它们的固定成本,并减少了每个 JVM 中的内存占用。 IBM 在 z/OS 平台上实现了共享类技术。Apple Computer Inc. 在 Mac OS X 上实现了名为 Java Shared Archive(JSA)的一种共享类,而 Sun 在 J2SE 1.5 版中引入了基于 JSA 技术的 Class Data Sharing (CDS)。让我们分析一下这些实现是如何工作的。 IBM 的实现 自 J2SE 1.3.1 以来,IBM 就在 z/OS 平台上提供了共享类技术的实现。这种实现是通过让一个主(或称 master) JVM 将核心系统类装载到共享内存完成的,那么这到底是什么意思呢? 分解堆 内存分为共享堆和 Java 堆。主 JVM 将系统堆(即共享堆)分配到共享内存中,这里是放置系统类的地方。系统堆在主 JVM 的生存周期中一直存在,并且不会受到垃圾收集(GC)的影响。每一个后续(或者 worker)JVM 附加到这个系统堆上,如图 1 所示,并为自己的 Java 堆分配非共享内存,它会受垃圾收集的影响。Java 堆包含特定于每一个 worker JVM 运行的应用程序的非共享类和所有实例化的对象。 图 1. 共享类分解堆 共享类装载器 每个 worker JVM 都可以通过将类放到共享类装载器的 classpath 中而将它们装载到共享堆中。共享类与普通类的装载方式一样——使用 parent-delegation 模式。 层次结构中的每一个类装载器检查其缓存,确定这个类是否已经装载。如果还没有装载,那么类装载器就向其父类装载器传递一个检查装载请求,这样一直上溯到层次结构顶部的 primordial 或者 bootstrap 类装载器。如果没有在任何缓冲区中发现这个类,那么每一个类装载器都会试图从自己的存储库中装载这个类,如果成功,就返回这个类。否则,它将请求传递给层次结构中下面的装载器。这种模型保证了首先检查最受信任的存储库,并防止信任程度低的代码通过采用与核心 API 成员相同的名字代替受信任的核心 API 类。 如果类是 primordial 类或者定义的类装载器是共享类装载器,那么类对象将在共享堆中创建,并且类标记为共享类。图 2 显示了 bootstrap 类装载器位于类装载器层次结构的顶部,并负责装载核心 API 中的类。这些类是信任程度最高的。扩展类装载器装载 extensions 目录中的标准扩展 JAR 文件中的类。共享应用程序类装载器可以用于共享用户或者应用程序类。 图 2. 类装载器层次结构 Java共享类(2)时间:2011-02-28 IBM Lakshmi Shankar但是在这种实现中,类到底是如何由多个 JVM 共享的呢? 假定 JVM 1 装载了 java/lang/String,这是一个由 bootstrap 类装载器装载的系统类。如果 JVM 2 想要装载 java/lang/String,由于它不能访问 JVM 1 的 bootstrap 类装载器缓存,所以它必须使用自己的 bootstrap 类装载器重新装载这个类。在这个例子中,JVM 不共享任何类,如图 3 所示。 图 3. 类没有跨 JVM 共享 因此,最好让 JVM 共享相同的类,如图 4 所描绘的。 图 4. 跨 JVM 共享的类 要解决这个问题,通过创建一个名为 namespace 的全局类缓存,将类缓存的概念加以扩展。每个 JVM 的类装载器必须在这个 namespace 上注册。当共享类装载器装载一个类时,它被同时放到本地类缓存和 namespace 中(如图 5 所示)。这样做使得其他 JVM 中的类装载器(在 namespace |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |