JVM

什么样的对象是垃圾?

JDK1.2:没有被引用的对象既是垃圾
JDK1.2之后:无法到达GC ROOTS顶点的对象即为垃圾

怎样判断对象是否被引用?

  • JDK1.2时期:引用计数算法

    • 对每个对象创建一个计数器,如果有一个引用指向它,其计数器+1,当一个引用不再指向他时,其计数器-1,最后判断这个计数器是否大于0,如果大于0,说明有引用指向它,如果不大于0,表示没有引用指向它,其即为垃圾。
      • 在循环引用中会失效在这里插入图片描述
        在这里插入图片描述
      • 根据引用计数算法:当a=null和b=null时,彼此之间还存在相互引用,它们的计数器大于0,所以并不是垃圾;但是引用一旦为null,对象无法被调用,本质上来说它们就是垃圾。所以引用算法存在缺陷!
  • 可达性算法:

    • 选取一个节点作为GC ROOTS,其他的引用和对象都去指向这个GC ROOTS,如果这些对象能够达到GC ROOTS顶点,那么说明这个对象不是垃圾;反之即为一个垃圾;指向GCROOTs的链叫做GC链
  • 根据可达性算法:当GC链1或者GC链2断裂时,两个对象都不是垃圾;但是当链1和2都断裂时两对象都无法到达GC ROOTS顶点,两个对象都是垃圾

可作为节点的对象
  • 虚拟机栈(栈帧中本地变量表所指向的对象)
  • 方法区中类静态属性引用的对象
  • 方法区的常量
  • native方法中引用的对象
对象的自我拯救
finalize
  • 对象的三种状态:
    • 可达(非垃圾)
    • 可恢复(对象由可达变为不可达的中间状态)
      • 当该对象满足以下两个条件时它可能调用finalize方法达到自我拯救的目的:
        • finalize方法被重写
        • finalize方法未被执行(一个对象的finalize方法能且只能被执行一次)
    • 不可达 (垃圾)
      finalize底层有一个低优先的finalizer线程,将这些需要执行的finalize方法放置在一个队列中,如果发现执行代价过高,则直接舍弃,不予执行
finally、final
  • finally:
    • finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下
  • final:
    • final可以用来修饰类,方法和变量
      • 修饰类:当用final修饰类的时,表明该类不能被其他类所继承。当我们需要让一个类永远不被继承,此时就可以用final修饰
        • final类中所有的成员方法都会隐式的定义为final方法。
      • 修饰方法:
        • 把方法锁定,以防止继承类对其进行更改。
          • final方法意味着“最后的、最终的”含义,即此方法不能被重写
          • 若父类中final方法的访问权限为private,将导致子类中不能直接继承该方法,因此,此时可以在子类中定义相同方法名的函数,此时不会与重写final的矛盾,而是在子类中重新地定义了新方法。
      • 修饰变量:final成员变量表示常量,只能被赋值一次,赋值后其值不再改变。
        • 当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。
        • final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值