0%

对象死亡判断

对象死亡判断

引用计数法

  • 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加1;当引用失效,计数器就减1;任何时候计数器为0的对象就是不可能再被使用的

    ​ 难以解决对象间的循环引用。除了对象 objA和objB相互引用这对方外,这两个对象之间再无任何引用。但是他们因为相互引用对方,导致他们的应用计数器都不为0,于是引用计数算法无法通知GC回收器回收他们。

可达性分析算法

  • 通过一系列的称为 “GC Roots”的对象作为起点,从这些节点开始想下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。

可作为 GC Roots 的对包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 本地方法栈(Native方法)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象

引用

  • 判定对象的存活与 “引用” 有关。
  • 强引用(StrongReference)
    • 我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。必不可少,垃圾收集器绝对不会回收他。当空间不足,Java虚拟机宁愿抛出 OutOfMemoryError 错误,是程序异常终止
  • 软引用
    • 如果一个对象具有软引用,可有可无,如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。
  • 弱引用
    • 可有可无,只具有弱引用的对象拥有更短暂的生命周期。在垃圾收集器线程扫描他所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
  • 虚引用
    • 形同虚设。如果一个对象仅持有引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。

不可达的对象并非 “不死不可”

  • 即使在可达性分析算法中不可达的对象,也并非是 “非死不可” 的,这时候它们暂时处于 “缓刑阶段”,要真正宣告一个对象死亡,至少需要经历两次标记过程;可达性分析算法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法, 或 finalize 方法已经被虚拟机调用过时, 虚拟机将这两种情况视为没有必要执行。
  • 被判定为需要执行的对象将会被放在一个队列中进行二次标记,除非这个对象与应用链上的任何一个对象关联,否则真的会被回收。

如何判断一个常量是废弃的常量?

  • 运行时常量池
  • 加入在常量池中存在字符串 “abc” , 如果当前没有任何 String 对象引用该字符串的话, 就说明常量 “abc” 就是废弃常量,如果这是发生内存回收的话而且有必要的话, “abc” 就会被系统清理出常量池。

如何判断一个类是无用的类

  • 方法区主要回收的是无用的类
  • 可以被回收
    • 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。
    • 加载类的 ClassLoader 已经被回收。
    • 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

----------- 本文结束啦感谢您阅读 -----------