一、什么内存会被回收
可达性分析算法
通过一系列的GC ROOT的对象作为超始点,从这些节点开始向下搜索,搜索所走的路径称为"引用链",当一个对象到GC ROOT之间没有任何引用链,则会对该对象进行一次标记,说明对象暂时是没用的
GC ROOT对象指:
虚拟机栈(栈帧中的局部变量表)中的引用对象
方法区中静态属性的引用对象
方法区中常量引用对象
本地方法栈中JNI引用对象
刚刚上面所说,经过可达性分析算法后,会对该对象进行一次标记,只能说明对象暂时是没用的,一个对象宣告死亡最少要经历两次标记,如果经过可达性分析算法后,如果对象到 GC ROOT 之间没有引用链,将会进行一次标记并且进行一次筛选,筛选的条件:
此对象没有重写finalize()方法
finalize()方法已经被执行过一次
如果满足这两个条件,说明没有必要执行
如果这个对象有实现finalize()方法,那这个对象将会放置在一个叫做F-QUEUE的队列中,由虚拟机自动建立,低优先级的执行。
二、什么时候回收
Jvm堆内存可分为:新生代(Eden、From、To),老年代,永久代
新生代:
新生代可分为Eden、From、To空间,占比:8:1:1,可以通过SurvivorRatio进行设置
当Eden空间满了后,会进行YGC,采用复制算法(ParNew、Parallel Scavenge),将还存活的对象复制到Survivor空间,然后清理掉Eden空间
老年代:
当新生代产生YGC时,会将前面Survivor中还存活的对象复制到老年代,如果此时,老年代空间不足(老年代使用了92%,CMS会被激活),会进行Full GC,采用(CMS、Parallel old),
CMS分为四个过程:
初次标记(STW)
并发标记
重新标记(STW)
并发清除