Root references
An object is dead really means it is useless. Only the programmer knows if an object is useless or not. In order for the program to decide if an object is useless, we can use compiler analysis, reference counting, or reachability analysis.

Reachability analysis assumes an object is live as long as it is reachable by the mutator. If an object's reference is contained by a slot of the mutator's stack, it's directly reachable. Those objects reachable from reachable objects are also reachable. So the issue for reachability analysis is to find out the references that are directly reachable, which are root references. The set of root references is root set.

The mutator's context has the data that are directly reachable, so to get root set is to find object references in the context. The context of a mutator refers to its stack and its register file (and some other thread-specific data). Global data are also directly reachable.

Root set enumeration
Normally, if a GC uses reachability to determine an object's liveness, GC needs to get a consistent snapshot of the mutator's context, so as to enumerate the root references. This is true for both stop-the-world (STW) and concurrent GC (mostly). "Consistent" means the snapshot looks like taken at a single time point. A consistent snapshot of root references are necessary for correctness, otherwise some live objects might be lost. Then the question is how to get the consistent mutator's context snapshot.

To get the consistent snapshot, a simple way is that the mutator suspends its execution during the root references enumeration. The snapshot is also consistent if the root set does not change during the enumeration process.

When a mutator suspends its execution, it is not necessarily able to enumerate the root references in its context, unless it book-keeps the reference information in its context. That is, it should be able to tell which stack slots have references, and which registers hold references. If GC can accurately gets the information, it is called precise root set enumeration; or it's imprecise.

(For imprecise enumeration, GC has to use some heuristics to conservatively guess the references from the context. So the GC is called conservative GC. This essay only discusses precise enumeration.)

Harmony supports precise root set enumeration with GC safe-point and safe-region.

Safe-point (or safepoint)
In order to support precise enumeration, JIT compiler should do additional work, because only JIT knows exactly stack frame info and register contents. When JIT compiles a method, for every instruction, it can book-keep the root reference information in case the execution is suspended at that instruction.

But to remember the info for every instruction is too expensive. It requires substantial space to store the information. This is also unnecessary, because only a few instructions will have the chances to be the suspension points in real execution. JIT only needs to book-keep information for those instruction points -- they are called safe-points. Safe-point means it is a safe suspension point for root set enumeration.

Btw, the ability of a compiler to know exact stack slots' information is not universally available in all programming languages. Only safe languages have the ability. For example, C/C++ doesn't.

Mutator suspension
The question to safe-points is, how we can guarantee that the mutator is suspended at safe-point.

There are basically two kinds of approaches to suspend a mutator, preemptively or voluntarily. The preemptive approach is to suspend the mutator whenever GC needs to start a collection. If it finds the mutator is suspended at an unsafe point, it will resume the mutator, rolling it forward to a safe-point. This was implemented in ORP [1], the predecessor of Harmony. But currently almost no JVM takes this approach.

The approach used in Harmony is voluntary suspension. When GC wants to trigger a collection, it simply sets a flag; the mutators poll the flag periodically, and will suspend once they find the flag is set. Those polling points are safe-points. It's mostly JIT's responsibility to insert the pollings at proper positions. Sometimes VM also needs to have some polling points.

Polling point
So where are the right places for polling GC trigger event? As I discussed above, we do not want to have polling points for every instruction. For voluntary suspension, a more serious problem is the polling overhead. So the basic principles for polling point insertion are: Firstly, polling points should be frequent enough so that GC does not wait too long for a mutator to suspend, because other mutators might be waiting for GC to free the space in order to continue. Secondly, polling points should not be too frequent to introduce big runtime overhead.

The best result is to have only adequate polling points that are necessary and sufficient. 
1. The mandatory polling points are the allocation sites. Allocation can trigger collection, so allocation site has to be a safe point. 
2. Long-time execution are always associated with method call or loop. So call sites and loop back sites are also expected polling points.

Those are the sites for polling points in Harmony: allocation sites, call sites and loop back sites. Mostly the runtime overhead is smaller than 1%. Unfortunately we found safe-point alone is not sufficient.

Safe-region
Why can safe-point alone be not sufficient? The reason is we forgot one case of long time execution. We forgot it because it's actually not long time execution, but long time idle. There are situations when the application can not respond promptly to a GC trigger event, such as sleep, or being blocked in a system call. These operations are out of JVM's control. JVM can not respond to GC trigger event in that period. So we introduce safe-region to solve the problem.

Safe-region is the section of code that no references are mutated in it, then it is safe to enumerate roots at any points of that region. In other words, the safe region is a big extended safe-point.

In safe-point design, the mutator polling for GC event will respond if the event is triggered. It responds by setting a ready flag when it's sure to suspend. Then the GC can proceed with root set enumeration. This is a hand-shaking protocol.

Safe-region just follows this protocol. The mutator sets the ready flag when it enters a safe-region. Before it leaves the region, it checks if GC has finished its enumeration (or collection), and no longer needs the mutator under suspension state. If it's true, it goes ahead and leaves the region; otherwise, it suspends itself as in a safe-point.

In Harmony implementation, we insert suspend_enable and suspend_disable to delimit the scope of safe-region.

Safe point的更多相关文章

  1. Warning: strftime(): It is not safe to rely on the system's timezone settings.

    当运行程序时,会出现如下警告: Warning: strftime(): It is not safe to rely on the system's timezone settings. You a ...

  2. The Safe Navigation Operator (&.) in Ruby

    The most interesting addition to Ruby 2.3.0 is the Safe Navigation Operator(&.). A similar opera ...

  3. 【转】php Thread Safe(线程安全)和None Thread Safe(NTS,非 线程安全)之分

    Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. ...

  4. workbench中safe update

    1.在workbench中表格显示为readonly ,更新时提示Error Code: 1175. You are using safe update mode and you tried to u ...

  5. A ship is always safe at the shore - but that is not what it is built for.

    A ship is always safe at the shore - but that is not what it is built for. 船靠岸边总是安全的,但那不是建造它的目的.

  6. php : Warning: strftime(): It is not safe to rely on the system's timezone settings.

    使用 Smarty 的时候出现这种警告: Warning: strftime(): It is not safe to rely on the system's timezone settings. ...

  7. mac下apache配置,解决It is not safe to rely on the system's timezone settings.

    之前一直转windows平台下做php,很少遇到问题.现在有了macbook,还在慢慢的熟悉中,搭建php开发环境,熟悉mac系统文档组织还有命令,颇费功夫. 今天我在mac下做一个php的练习,用到 ...

  8. 抛弃强大的TFS ,借助于BugTracker.NET + Visual Source Safe + SourceLink搭建项目开发环境

    微软公司的Team Foundation Server是个强大的项目管理工具,如果用.NET开发,它应该是首选的项目管理平台.TFS的成本比较高,而且和Visual Studio集成紧密.比如TSF有 ...

  9. 使用Source Safe for SQL Server解决数据库版本管理问题

    简介     在软件开发过程中,版本控制是一个广为人知的概念.因为一个项目可能会需要不同角色人员的参与,通过使用版本控制软件,可以使得项目中不同角色的人并行参与到项目当中.源代码控制使得代码可以存在多 ...

  10. 暴力枚举 + 24点 --- hnu : Cracking the Safe

    Cracking the Safe Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit u ...

随机推荐

  1. Weblogic部署gbk编码的项目乱码

    问题描述: weblogic默认部署的项目编码utf-8,由于项目特殊编码gbk导致打开项目中文全是乱码! 心哇凉哇凉.... 问题解决: 01.调休jvm参数 xxx_domains/bin/set ...

  2. oracle 、mysql、 sql server使用记录

    oracle .mysql. sql server使用记录 mysql常用命令: mysqld --启动mysql数据库 show databases; -- 查看数据库 use database; ...

  3. Windows下node.js安装及环境配置

    1. 安装 官网下载node.js的安装版,一路next,中间可以自定义安装路径 完成后安装目录内容如下 cmd下检查是否安装成功 新版Node.js已自带npm,所以安装Node.js时会一起安装, ...

  4. MySQL-join的实现原理、优化及NLJ算法

    案例分析: select c.* from hotel_info_original c left join hotel_info_collection h on c.hotel_type=h.hote ...

  5. Swift3 URL编码、解码用法addingPercentEncoding

    我们请求一个url时,最好要对其编码,转换成url识别的字符,以应对url里可能存在的中文.特殊符号等. swift3之前用法: url.stringByAddingPercentEscapesUsi ...

  6. 系统监控nagios–安装

    安装:环境:CentOS6.0 32bit 1.先相关软件包 yum install httpd php gcc glibc glibc-common gd gd-devel make 2.创建用户信 ...

  7. MySQL安装Altas

    准备工作:需要先把MySQL主从配置好. 0.下载altas:打开https://github.com/Qihoo360/Atlas/releases wget https://github.com/ ...

  8. Swift 类型别名

    类型别名 在 Swift 语言中使用 typealias 关键字定义类型别名. typealias ShortInteger = Int8

  9. 【Algorithm】九种常用排序的性能分析

    最近间间断断的将9种排序算法用C实现,并且将其以博客笔记的形式记录下来,其中各个排序算法的描述部分特别参考了CSDN上太阳落雨的博客!现在就该来综合的分析这九种排序,让我们先来看看其算法复杂度和稳定性 ...

  10. C# 两个时间相减 返回 对应天时分秒

    "; //string sdsdsdsds = "1"; , '); //不足2位 就补充0 足2位 就不变 DateTime dts1 = DateTime.Now; ...