深入学习JVM-JVM 安全点和安全区域

JVM进行垃圾回收是一个非常复杂的过程,如何进行垃圾标记、什么时候进行垃圾、如果进行垃圾回收等等都非常复杂,当前主流测JVM在垃圾回收时都会进行STW(stop the world),即使宣称非常快的CMS垃圾回收期早期也会STW标记垃圾状态。那么这里有个问题,什么时候进行标记对象是否可以被回收呢?

CPU在执行运算过程时需要把数据从内存中载入到寄存器,运算完后再从寄存器中载入到内存中,Java中对象地址也是这么个过程,设想如果一个Java线程分配一个对象,此时对象的地址还在寄存器中,这时候这个线程失去了CPU 时间片,而此时STW GC发现没有任何GC ROOTS与该对象关联起来,此时这个对象呗认为是垃圾并被回收了,之后CPU重新获得时间片后发现此时对象已经不存在了这时候程序就GG了。

因此不是在任何时候都可以随便GC的,复杂的JVM早就考虑到这个问题,在JVM里面引入了一个叫安全点(Safe Point)的东西来避免这个问题。GC的目的是帮助我们回收不再使用的内存,在多线程环境下这种回收将会变得非常复杂,要安全地回收需要满足一下两个条件:

1.堆内存的变化是受控制的,最好所有的线程全部停止。

2.堆中的对象是已知的,不存在不再使用的对象很难找到或者找不到即堆中的对象状态都是可知的。

为了准确安全地回收内存,JVM是在Safe Point点时才进行回收,所谓Safe Point就是Java线程执行到某个位置这时候JVM能够安全、可控的回收不会导致上所说的回收正在使用的对象。

猜你喜欢

转载自my.oschina.net/wenbo123/blog/1822414