实时Java,第4部分 - 实时垃圾收集 - 编程入门网
其收集循环实现一个压缩或碎片整理阶段。清理完成后,如果分配请求无法满足,则系统将尝试移动堆中现有的活对象以便将两个或更多的自由块合并成一个更大的块。这个阶段有时作为一个随需应变的特性来实现,被嵌入到收集器的结构(例如半空间收集器)中,或以一种增量的形式来实现。每个这样的系统都有自己的平衡方法,但一般说来压缩阶段在时间和工作上都耗费颇多。
WebSphere Real Time 中当前版本的 Metronome 没有实现压缩系统。为使碎片不成为一个问题,Metronome 使用 arraylet 将标准的线性表示分解为若干个不连续的小块,可以对这些小块进行彼此独立的分配。 图 6 演示了数组对象作为 spine(它是可由堆上的其他对象引用的中心对象和惟一实体)和一系列的 arraylet 叶子(包含有实际的数组内容)出现: 图 6. Arraylet arraylet 叶子不由其他的堆对象引用,并且可能在堆中的任何位置以任意顺序分布。这些叶子具有固定的大小,允许对元素的位置进行简单的计算,这是一个附加的迂回。如图 6 所示,spine 中由于内部碎片导致的内存使用开销已经通过将叶子的所有 trailing 数据包含到 spine 中而得到优化。 注意,这种格式意味着数组 spine 可能成长到无限制的大小,但是在现有的系统中还没有发现这是一个问题。 实时Java,第4部分 - 实时垃圾收集(5)时间:2011-06-22 Benjamin Biron Rya调度 GC 时间量 为了给 GC 调度确定性暂停,Metronome 使用了以下两个不同的线程来完成一致性调度和短暂连续的暂停时间: alarm 线程。为了确定地调度 GC 时间量,Metronome 使用 alarm 线程来用作心跳机制。alarm 线程具有很高的优先级(比系统中所有其他的 JVM 线程的优先级都要高),它的唤醒速度与 GC 量子时间段相同(Metronome 中为 500 微秒),并负责决定是否应该调度某个 GC 时间量。如果应该调度,则 alarm 线程必须暂停运行 JVM 并唤醒 GC 线程。alarm 线程只在一个很短的时间段内处于活动状态(通常低于 10 微秒)并随应用程序静默的执行。 GC 线程。GC 线程在一个 GC 时间量期间执行实际工作。GC 线程必须首先完成对 alarm 线程启动的 JVM 的暂停。然后才能在剩余的时间内执行 GC 工作,在时间量临近结束时将自身调回休眠状态并恢复 JVM 的运行。如果 GC 线程无法在时间量结束前完成预定的任务项目,那么也可以抢占性地进入休眠。对于 RTSJ 而言,GC 线程的优先级比除 NHRT 之外的所有 RT 线程的优先级都要高。 协作暂停机制 虽然 Metronome 使用一系列小的、步进式的暂停来完成一个 GC 循环,但是它仍然必须以 STW 方式为每个时间量暂停 JVM。对于每个这样的 STW 暂停,Metronome 在 J9 虚拟机中使用协作暂停机制。这个机制不依赖任何特殊的本地线程功能来暂停线程。作为替代,它使用了一个异步形式的消息传递系统来通知 Java 线程:必须释放对内部 JVM 结构(包括堆)的访问并进入休眠,直至被告知恢复处理。J9 虚拟机中的 Java 线程周期性地检查是否发出了暂停请求,如果已经发出,则它们将执行以下步骤: 释放所有使用的内部 JVM 结构。 将所有使用的对象引用存储在良好描述的位置。 告知中央 JVM 暂停机制已经到达安全点。 休眠并等待相应的恢复。 一旦恢复,线程将重新读取对象指针并重新获取其先前占用的 JVM 相关结构。释放 JVM 结构的操作让 GC 线程以一种安全的形式处理这些结构;对部分更新的结构进行读和写操作可能导致不可预测的行为和冲突。通过存储和重新加载对象指针,线程给 GC 在 GC 时间量期间提供了更新对象指针的机会,如果对象作为任何类似压缩的操作的一部分移动时有此更新必要。 因为暂停机制与 Java 线程协作,所以每个线程中的周期性检查应该用尽可能小的时间间隔分开,这一点 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |