哪些内存需要接纳?
哪些内存需要接纳是垃圾接纳机制第一个要思量的问题,所谓“要接纳的垃圾”无非就是那些不行能再被任何途径利用的工具。那么如何找到这些工具?
1、引用计数法
这个算法的实现是,给工具中添加一个引用计数器,每当一个处所引用这个工具时,计数器值+1;当引用失效时,计数器值-1。任何时刻计数值为0的工具就是不行能再被利用的。这种算法利用场景许多,可是,Java中却没有利用这种算法,因为这种算法很难办理工具之间彼此引用的环境。看一段代码:
/** * 虚拟机参数:-verbose:gc */ public class ReferenceCountingGC { private Object instance = null; private static final int _1MB = 1024 * 1024; /** 这个成员属性独一的浸染就是占用一点内存 */ private byte[] bigSize = new byte[2 * _1MB]; public static void main(String[] args) { ReferenceCountingGC objectA = new ReferenceCountingGC(); ReferenceCountingGC objectB = new ReferenceCountingGC(); objectA.instance = objectB; objectB.instance = objectA; objectA = null; objectB = null; System.gc(); } }
看下运行功效:
[GC 4417K->288K(61440K), 0.0013498 secs] [Full GC 288K->194K(61440K), 0.0094790 secs]
看到,两个工具彼此引用着,可是虚拟机照旧把这两个工具接纳掉了,这也说明虚拟机并不是通过引用计数法来鉴定工具是否存活的。
2、可达性阐明法
这个算法的根基思想是通过一系列称为“GC Roots”的工具作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个工具到GC Roots没有任何引用链(即GC Roots到工具不行达)时,则证明此工具是不行用的。在Java语言中可以作为GC Roots的工具包罗:
· 虚拟机栈中引用的工具
· 要领区中静态属性引用的工具
· 要领区中常量引用的工具
· 当处所法栈中JNI(即Native要领)引用的工具
4种引用状态
在JDK1.2之前,Java中引用的界说很传统:假如引用范例的数据中存储的数值代表的是另一块内存的起始地点,就称这块内存代表着一个引用。这种界说很纯粹,可是过分于狭隘,一个工具只有被引用可能没被引用两种状态。我们但愿描写这样一类工具:当内存空间还足够时,则能保存在内存中;假如内存空间在举办垃圾收集后还长短常告急,则可以丢弃这些工具。许多系统的缓存成果都切合这样的应用场景。在JDK1.2之后,Java对引用的观念举办了扩充,将引用分为强引用、软引用、弱引用、虚引用4种,这4种引用强度依次削弱。
1、强引用
代码中普遍存在的雷同”Object obj = new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会接纳掉被引用的工具
2、软引用
描写有些尚有用但并非必须的工具。在系统将要产生内存溢出异常之前,将会把这些工具列进接纳范畴举办二次接纳。假如这次接纳还没有足够的内存,才会抛出内存溢出异常。Java中的类SoftReference暗示软引用
3、弱引用
描写非必须工具。被弱引用关联的工具只能保留到下一次垃圾接纳之前,垃圾收集器事情之后,无论当前内存是否足够,城市接纳掉只被弱引用关联的工具。Java中的类WeakReference暗示弱引用
4、虚引用
这个引用存在的独一目标就是在这个工具被收集器接纳时收到一个系统通知,被虚引用关联的工具,和其保留时间完全不要紧。Java中的类PhantomReference暗示虚引用
要领区接纳
虚拟机类型中不要求要领区必然要实现垃圾接纳,并且要领区中举办垃圾接纳的效率也确实较量低,可是HotSpot对要领区也是举办接纳的,主要接纳的是废弃常量和无用的类两部门。判定一个常量是否“废弃常量”较量简朴,只要当前系统中没有任何一处引用该常量就好了,可是要鉴定一个类是否“无用的类”条件就要苛刻许多,类需要同时满意以下三个条件:
1、该类所有实例都已经被接纳,也就是说Java堆中不存在该类的任何实例
2、加载该类的ClassLoader已经被接纳
3、该类对应的java.lang.Class工具没有在任那里所被引用,无法在任那里所通过反射会见该类的要领
在大量利用反射、动态署理、CGLib等ByteCode框架、动态生成JSP以及OSGi这类频繁自界说ClassLoader的场景都需要虚拟机具备类卸载成果,昆山软件开发,以担保要领区不会溢出。
垃圾接纳算法
第一步考量了哪些工具举办接纳后,第二步自然是如何对工具举办接纳了。这里主要写几种垃圾接纳算法的思想。
1、标志-排除(Mark-Sweep)算法