1.概述
在JVM的垃圾回收算法进行垃圾回收的时候,通常分为两个阶段。
标记阶段,在这个阶段主要是明确到底哪个对象才是需要被回收的垃圾对象。
清除阶段,在这个阶段是真正进入垃圾回收的阶段。
2.垃圾标记算法
2.1 引用计数算法
算法的核心思想:每个对象保留一个引用计数器属性,如果这个对象被其他对象所引用,则这个计数器就会进行加一的操作。当这个计数器的数值为0的时候,这个对象就可以被随时回收,因此这个方法的实时性很好。
算法的缺点:如果有多个对象相互引用,形成了一个环。但是,这个环内的对象,没有被外界的对象引用。也就是循环引用的现象发生的话,这个引用计数算法就失效了,同时造成了内存泄漏的问题。这个垃圾标记算法在Java中是没有被采用的,而在Python中被采用,在python中是通过weakref,弱引用去解决的循环引用的问题。
2.2 可达性分析算法
首先介绍一下什么是GCRoot。
这个GCRoot是和回收堆中的对象有关,可以这样抽象,只要这个对象是在非堆中指向了堆空间对象的引用,则可以视为GCRoot。具体地,JVM栈中引用的对象和堆中的对象建立联系,本地方法栈中的引用对象,在常量池中的引用对象,静态变量的引用对象等非堆空间的对象。
根据上面对于GCRoot的共性分析,可以这样认为,对于新生代这一部分堆数据的回收,老年代如果有关于新生代对象的引用,则老年代也属于GCRoot。
垃圾对象的判断:以GCRoot对象为起点,从上到下进行搜索,如果某些对象可达,则这些对象不可以被视为垃圾。如果不可达则视为垃圾对象
小结
从可达性分析算法的执行过程中可以看出,在进行垃圾回收的时候,必须要进行STW,否则对象是否可达的情况可能会发生变化。因此,需要暂停一些事情,专门进行垃圾标记。