回收内存判断
- 引用计数法(不适用)
- 对象存在一个引用计数器。当一个地方引用它,则计数器+1;引用失效则-1。当计数器为0时,即无引用关系。
- 实现简单,判断效率高
- 存在循环引用的问题。两个对象之间存在相互引用,但对外已经无法被访问,应该被回收,但是存在循环引用,导致无法回收。
- 可达性分析算法(gc-roots)
- Gc Roots
- 虚拟机栈(栈帧中的局部变量表)引用的对象
- 方法区的静态变量引用对象
- 方法区的常量引用对象
- 本地方法栈JNI--native的引用对象
- 通过“GC Roots”的对象作为起始,向下搜索对象路径,称为引用链。
- 当对象与GC Roots之间没有引用链,则该对象不可达。
- Gc Roots
- 引用类型
- 强引用(Strong Reference)
- 通过关键字new创建的对象所关联的引用就是强引用。
- 当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),也不会靠回收具有强引用的“存活”对象来解决内存不足的问题。
- 软引用(Soft Reference)
- 只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象:即JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象。
- 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,虚拟机就会把这个软引用加入到与之关联的引用队列中。
- 应用场景:软引用通常用来实现内存敏感的缓存。
- 弱引用(WeakReference)
- 在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
- 弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,虚拟机就会把弱引用加入到与之关联的引用队列中。
- 应用场景:弱应用同样可用于内存敏感的缓存。
- 虚引用(PhantomReference)
- 如果对象仅持有虚引用,那么和没有引用一样,无法通过虚引用访问对象的任何属性或函数,可以被垃圾回收器回收。
- 幻象引用仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。
- 虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
- 可以通过判断引用队列中是否已经加入虚引用,来了解被引用的对象是否将要被垃圾回收。如果发现虚引用已经被加入到引用队列,那么可以在所引用的对象被回收之前采取一些行动。
- 对于软引用和弱引用之类,垃圾回收可能存在二次确认的问题,以保证没有被改变为强引用。
- 强引用(Strong Reference)
- 判断对象死亡
- 1.在对象进行可达性分析以后,发现与GC Roots之间无引用链,则被第一次标记并进行筛选。
- 2.筛选条件:此对象是否有必要执行finalize()。当对象没有覆盖finalize()或已被执行,则视为“无必要执行”。
- 3.若有必要执行,则对象被放入F-Queue队列,并有虚拟机建立的低优先级的Finalizer线程执行。
- 不保证finalize()被执行或执行完成,防止finalize执行缓慢或死循环,导致内存回收崩溃。
- finalize()在整个生命周期内最多被执行一次。若对象通过该方法被拯救以后,再次进行回收,则认为该方法已经被调用过。
- 4.GC对F-Queue中的对象进行小规模的第二次标记。若有对象与GC Roots建立引用链,则会被移除“即将回收"的集合。
- 方法区回收
- 废弃常量
- 没有相关的引用即可被回收。
- 无用的类
- 该类的所有实例已经被回收
- 加载该类的ClassLoader已被回收
- 该类对应的Class对象没有被引用,无法通过反射访问该类方法。
- 满足无用类的回收条件仅仅代表可以被回收。
- 废弃常量