Sat*_*ish 1 java garbage-collection
我知道当新的对象分配失败或调用System.gc()时会触发GC.每个GC算法都建议,作为第一步,GC线程将挂起所有应用程序线程,以便它们不会影响GC活动.
但我想了解GC如何挂起所有正在运行的线程?我的意思是JVM定义了任何安全点,例如,内存分配(新对象创建)或方法调用,当应用程序线程到达这些安全点时,它们将被阻止以防止GC锁定.这是真的吗?如果是这样,那么如何只执行如下简单计算的应用程序线程(我知道实际上这永远不会发生),它会被暂停吗?
while(true) {
a = a + s;
s = s + a;
// some computation that doesn't touch any JVM safe points
}
Run Code Online (Sandbox Code Playgroud)
在这些情况下,GC活动是否会在不挂起这些应用程序线程的情况下继续(并在以后尝试跨越安全点时暂停/阻止,例如对象分配)?
但我相信,GC始终等待这些应用程序线程进入安全点并在继续之前暂停它们.我的假设是真的吗?
但我想了解GC如何挂起所有正在运行的线程?
热点实现使用安全点轮询.报价:
安全点如何工作?
HotSpot JVM中的安全点协议是协作的.每个应用程序线程都会检查安全点状态,并且需要将自身置于安全状态的安全状态.对于已编译的代码,JIT在某些点(通常是从调用返回或循环的后跳)后的代码中插入安全点检查.对于解释代码,JVM具有两个字节的代码分派表,如果需要安全点,JVM会切换表以启用安全点检查.
安全点状态检查本身以非常狡猾的方式实现.正常的内存变量检查需要昂贵的内存屏障.但是,安全点检查是在内存读取障碍时实现的.然后需要安全点,JVM取消映射页面,该地址在应用程序线程上引发页面错误(由JVM的处理程序处理).这样,HotSpot维护其JITed代码CPU管道友好,但确保正确的内存语义(页面取消映射强制内存屏障处理核心).
来自机械同情邮件列表的更详细描述.
Run Code Online (Sandbox Code Playgroud)// some computation that doesn't touch any JVM safe points
如果编译器可以证明它们在有限的时间内完成,那么编译器只允许这些事情.否则它会插入安全点轮询
| 归档时间: |
|
| 查看次数: |
1049 次 |
| 最近记录: |