GC如何暂停/阻止应用程序线程 [英] How GC suspends/blocks the application threads

查看:434
本文介绍了GC如何暂停/阻止应用程序线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道当新的对象分配失败或调用System.gc()时触发GC。每个GC算法都建议,作为第一步,GC线程将暂停所有应用程序线程,以便它们不会影响GC活动。



但我想了解GC如何挂起所有正在运行的线程?我的意思是说,有任何由JVM定义的安全点,例如,内存分配(新对象创建)或方法调用,并且当应用程序线程到达这些安全点时,它们将被阻止对GC锁定。这是真的吗?如果是这样,那么应用程序线程如何做一个简单的计算如下(我知道在现实中这绝不会发生),它会被暂停吗?

<$ p $ (true){
a = a + s;
s = s + a;

//一些不会触及任何JVM安全点的计算

code


在这些情况下,GC活动是否继续进行而不暂停这些应用程序线程(并且稍后当它们尝试跨越安全点时暂停/阻止,例如对象分配)?

但我相信,GC总是等待这些应用程序线程进入安全点并在继续之前暂停它们。我的假设是否正确?

解决方案


但我想了解GC如何暂停所有正在运行的线程?

热点实施使用 safepoint polling 。引用:
$ b


安全点的工作方式



HotSpot JVM中的Safepoint协议是
合作。每个应用程序线程检查安全点状态,并且
将安全状态置于安全状态。对于已编译的代码,
JIT在某些点(通常在
从调用返回或在循环的后退跳转后)插入代码中的安全点检查。对于解释代码,JVM
有两个字节代码分派表,如果需要安全点,JVM
将切换表以启用安全点检查。



安全点状态检查
本身是以非常狡猾的方式实现的。正常的内存变量
check需要昂贵的内存屏障。虽然,安全点检查
是在内存读取屏障时执行的。然后需要safepoint,
JVM取消映射带有该地址的页面在应用程序
线程(由JVM的处理程序处理)上引发页面错误。这样,HotSpot
维护JITed代码CPU流水线友好性,同时确保正确的
内存语义(页面取消映射迫使处理
内核的内存屏障)。


更详细的说明 from the mechanical-sympathy mailing list。







  //一些不会触及任何JVM安全点的计算


如果编译器可以证明它们在有限的时间内完成,那么只允许这些东西。否则,它会插入安全点轮询


I understand that GC gets triggered when a new object allocation fails or System.gc() is called. Every GC algorithm suggests that as a first step the GC thread will suspend all the application threads so that they won't affect the GC activity.

But I would like to understand how GC suspends all the running threads? I mean is there any safe points defined by JVM, for example, memory allocation (new object creation) or method invocation, and when application thread reaches these safe points they will be blocked against a GC lock. Is it true? If so, then how about an application thread that does only a simple computation as follows (I know in reality this will never happen), will it ever get suspended?

while(true) {
    a = a + s;
    s = s + a;

    // some computation that doesn't touch any JVM safe points 
}

In these cases, does GC activity carry on without suspending these application threads (and suspend/block later when they try to cross a safe point, for example object allocation)?

But i believe, GC always waits for these application threads to enter the safe points and suspends them before proceeding. Is my assumption true?

解决方案

But I would like to understand how GC suspends all the running threads?

The hotspot implementation uses safepoint polling. To quote:

How safepoints work?

Safepoint protocol in HotSpot JVM is collaborative. Each application thread checks safepoint status and park itself in safe state in safepoint is required. For compiled code, JIT inserts safepoint checks in code at certain points (usually, after return from calls or at back jump of loop). For interpreted code, JVM have two byte code dispatch tables and if safepoint is required, JVM switches tables to enable safepoint check.

Safepoint status check itself is implemented in very cunning way. Normal memory variable check would require expensive memory barriers. Though, safepoint check is implemented as memory reads a barrier. Then safepoint is required, JVM unmaps page with that address provoking page fault on application thread (which is handled by JVM’s handler). This way, HotSpot maintains its JITed code CPU pipeline friendly, yet ensures correct memory semantic (page unmap is forcing memory barrier to processing cores).

more detailed description from the mechanical-sympathy mailing list.


 // some computation that doesn't touch any JVM safe points 

The compiler only allows those things if it can prove that they finish in a finite amount of time. Otherwise it inserts safepoint polls

这篇关于GC如何暂停/阻止应用程序线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆