安全点(safepoint): JVM并不是为每条指令都生成OopMap,当JVM进入特定的位置,记录的信息才能进能暂停用户线程进入GC流程,这个点称为安全点。
个人理解:好比战争年代的防空洞,当在外面打战的时候随时可能会干掉,而到防空洞可以修整。
怎么选安全点呢?
安全点的选择不能太少,太少会导致GC时间过长,如果太多会导致频繁GC,所以选择了:循环的末尾、方法返回前、调用方法之后、抛异常的位置 作为安全点。
实现中断的策略?
抢先式中断(Preemptive Suspension)
垃圾收集发生时,系统首先把所有用户线程全部中断,如果发现有用户线程中断的地方不在安全点上,就恢复这条线程执行,让它一会再重新中断,直到跑到安全点上。
特点:
不需要线程主动去配合
没有虚拟机实现采用抢先式中断来暂停线程响应GC事件。
主动式中断(Voluntary Suspension)
先设置标志位,所有线程执行过程时会不停地主动轮询这个标志,当发现中断标志为真时就自已在最近的安全点上主动中断挂起。
特点:
不直接对线程操作
设置标志位
什么是内存保护陷阱?
通过一条汇编指令来完成安全点轮询和触发线程中断。
安全区域:能够确保某一段代码片段之中,引用关系不会发生变化!
个人理解:就类似于度河,在过度阶段你只能待在船上,除非等待到岸,并且通知可以放行才能走。
什么叫程序不执行?
没有分配处理器时间 比如:用户线sleep状态或者Blocked状态,无法响应虚拟机中断请求!
注意:HotSpot没有为每条指令都生成OopMap
最后
JVM在进行GC之前,需要具体是什么时间点,什么阶段可以进行GM所以有了安全点概念,而进行GC的时候需要暂停所有的用户进程,所以需要保持所有的引用关系不变化,这种称为“安全区域”。
参考:
https://blog.csdn.net/shangshanzixu/article/details/113828363
http://t.zoukankan.com/newAndHui-p-12246015.html
https://blog.csdn.net/fsjwin/article/details/109235471
https://www.jianshu.com/p/c79c5e02ebe6