上一章我们提到,如果频繁的创建OopMap,会造成内存的极大开销。
而的确,JVM并没有如此频繁的创建OopMap,而是在一个特定的位置,统一的生成。
这个特定的位置我们称为安全点,
安全点包含以下几种位置。
1、方法调用结束后。
2、循环跳出之后。
3、抛出异常之后
对于安全点而言,当线程进入安全点的时候,就可以收集到足够的GCRoot,可以进行垃圾回收。
的确,jvm规定只有线程进入安全点之后,才允许进行垃圾回收!
所以,安全点的设置很重要,如果太多,那垃圾回收就会过于频繁,加剧系统的负担;如果太少,那垃圾回收的频率就会很低,有内存溢出的风险。
此外,当垃圾回收发生的时候,如何让线程都处于安全点呢?
这里有两种方案:
1、抢先式中断:抢先式中断不需要线程的执行代码主动的配合,在垃圾回收发生时,系统把所有的用户线程中断,如果发现有线程不在安全点上,则让该线程继续运行至最近的安全点才中断。
2、主动式中断:主动式中断在垃圾回收发生时,不直接对线程进行操作,而是设立一个标识,让所有的线程不断的去轮询这个标识,如果标识为真,则线程会在最近的安全点主动的挂起。