《深入理解虚拟机》阅读笔记-回收内存判断

回收内存判断

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

猜你喜欢

转载自blog.csdn.net/jiangxiayouyu/article/details/105614222