实时Java,第5部分 - 编写和部署实时Java应用程序 - 编程入门网
在于我们在传统基于堆的环境和 NHRT 的非堆环境之间引入了一个接口。稍后您将看到,在处理这个接口时需要格外谨慎。
图 7 是该架构的高级示意图: 图 7. 高级架构图 现在您已经对希望 NHRT 应用程序实现的功能有了一点头绪,下一个挑战就是找出系统在其中完成这些任务的存储区。 RT Java 中的非堆内存 要为我们的设计应用作用域和不朽内存,首选需要对其工作原理略知一二。 在不朽内存中创建的对象从来不会被清除,在应用程序的生命周期中一直存在。即便是您已经使用完了对象,它依然会占据无法回收的空间。这无疑给编程人员保持跟踪在不朽内存中创建的所有对象并避免长期不断创建对象的职责造成了阻碍。不朽内存泄漏是 RT Java 应用程序中的常见错误源头。 在作用域内存中创建的对象则在于其中创建它们的作用域的生命周期中存在。作用域内存的每个区域都有一个引用计数;一个线程进入 scoped 内存的一个区域时,该引用计数将递增,当该线程离开时,引用计数则递减。当引用计数为 0 时,作用域内的对象将被释放。作用域存储区的大小有最大值,这是在其创建时指定的,并且必须用于它们的目标任务。RT 应用程序的设计者通常会将作用域与指定任务关联在一起,以便有效调优。作用域不适于使用的内存数不可预测的任务,因为作用域的大小是固定的,必须预先声明。 实时Java,第5部分 - 编写和部署实时Java应用程序(11)时间:2011-06-22 Caroline GoughSweet Factory 示例的内存架构 上面我们简要介绍了非堆内存,现在可以将其应用于之前所设计的系统了。 从内存的角度来看,审计系统比较简单。它运行在堆内存的一个 java.lang.Thread 之上。无论您使用的是标准 Java 线程还是基于堆的 RT 线程,在垃圾收集器管理的内存中进行字符串操作和 I/O都是易于察觉的,因为这些操作会以令人惊奇的方式耗用大量内存。 我们的系统中的其他线程是 NHRT,根据定义,它们不能使用 Java 堆来分配对象。我们的选择是限于作用域和不朽内存的某种组合。 所有线程都有一个初始存储区,将在该线程的生命周期中使用。在我们的设计中,我们的 NHRT 是长期运行的,因此无论选择什么作为初始存储区,在初始启动后都绝对不能使用其中的任何内存,因为无论使用的是作用域还是不朽 —— 内存都将无法再被清空,最终将被耗尽。 当前存储区仅被对象分配消耗,因此内存管理的一种途径就是仅使用固定数量的对象,或者完全避免使用对象。通过使用栈上的原始值,我们就可以在不使用当前存储区的前提下完成工作。(栈是内存的一部分,存储函数参数和方法中使用的字段。它与 Java 堆和不朽或作用域内存分离,但无法容纳对象 —— 仅能容纳原始值或对象引用。) 然而,Java 语言机器类库鼓励您使用对象来达成目标。因此,对于本例,我们将假设 NHRT 需要执行的操作会创建一些对象,并在每次执行时占用一些内存。 在这个场景中(系统必须在未指定的较长时间内具有一个平面内存配置文件,但依然会创建对象),最佳方法是在不朽内存中启动线程,并为指定、限定的任务分配区域。 在一个线程运行时,只要它需要执行一项任务,就应该进入一个作用域(其大小是专为该任务校准的)、执行任务,然后离开作用域以释放所占用的内存。要使此技术更为健壮,您执行的任务必须是限定的,那样您才能够预测并校准所需的作用域内存数量。 在多个线程间共享作用域是可行的,但比较困难,原因就是内存作用域的单亲规则(参见 单亲规则)。管理共享的作用域并不简单,因为一个作用域只有在所有的线程都离开它时才能被回收。这也就是说,作用域的大小必须合理设定,以允许多个线程同时执行任务。 总之,如果您坚持一次对一个线程上的一个任务使用一个作用域 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |