1、哪些需要回收
1.1引用计数算法
给对象添加一个应引用计数器,有一个地方引用他,就加一,当引用失效就减一,任何时刻计数器为0的对象就是不可能再被使用的。
很少使用,因为他很难解决对象之间相互引用的问题。
1.2可达性分析
从被称为GC ROOTS的对象开始,向下搜索,搜索走过的路路径被称为引用链,当对象到GC ROOTS没有引用链相连,则对象是不肯可用的
GC Roots包包括一以下情况
虚拟机栈中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
1.3引用的分类
引用讲将对象简单的分为可用的和不可用的是比价狭隘的,因为有一类对象当:当内存空间还足够的时候能被留在内存中,如果内存空间在进行垃圾收集后内存还是紧张的话,则抛弃这类对象
因此引用被分为四种强度
强引用:强引用在,被引用的对象就永远不会被回收
软引用:在内存溢出之前,对象被列进回收范围进行二次回收,如果第这次回收内存还是不够则会抛出内存溢出
弱引用:无论内存是否足够,垃圾回收时都会被回收
虚引用:不构成影响,也无法通过虚引用得到对象实例,只是为了在这个对象被回收时收到一个系统通知
1.4二次标记
-在可达性分析中不可达的对象也非非死不可的,要让他真正死亡需要经过二次标记过程
没有与GC ROOTS相连的话,会被第一次标记并且进行筛选:筛选条件是对象是否有必要执行finalize方法,如果没有重写方法或者方法被调用过一次,则没有必要执行筛选
被筛选判断有必要执行finalize方法,则讲对象放入F-QUENE队列中,然后由一个虚拟机自动建立的低优先级的Finalize线程去执行
GC对队列中的对象进行二次标记,对象在finalize中拯救自己(重新与引用链上的任何对象简建立关系,例如把自己赋给类变量或对象的成员变量),则将在二次标记时讲将他移出'即将回收'的集合。
1.5方法区的回收
主要回收废弃常量和无用的类
无用的类:
该类的所有实例都已经被回收了
加载该类的classLoader已经被回收
该类对应的java.lang.Class对象没有在任何地方被引用,无法通过反射访问该类的方法
2、回收算法
2.1标记--清理
先标记出所有药要回收的对象,标记完成后统一清理
两个问题:
标记和清理两个过程效率都不高
标记清除后会产生大量不连续的内存碎片,以后需要分配大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集
2.2复制(被用来回收新生代)
将内存分为两块,一块不够用时,将还活着的对象复制到另一块内存,然后被把已经使用的空间一次清理,有优点是效率高,不用考虑内存碎片,缺点是内存只有一半,代价高
改进用法,将内存分按8:1:1分为一个Eden和两个Survivor区域,新生的放在Eden中,垃圾收集时,将Eden和在用的Survivor中活着的对象复制如另一块Survivor中,然后将两块内存清理掉,这样新生代的容量达到90%
当Survivor内存不够用的话,需要依赖其他内存(老年代)进行分配担保
2.3标记--整理(老年代)
先标记,然后先将所有存活对象都向一段端移动,然后直接清理掉端边界之外的内存。
3、如何实现
4、GC收集器
serial
paller
pallrnew
serial old
paller old
cms
G1
网友评论