本文介绍: 除了以上四种引用,还存在一种终结器引用,当GC回收一个重写了finalize()方法的对象时,JVM会给被回收对象创建一个终结器引用,同时将该引用放入引用队列,通过一个FinalizerHandler线程去处理引用队列当中的终结器引用,首先是判断被回收对象是否执行了finalize()方法,如果没有则执行,等到下一次GC时才会去释放该对象。所谓可达性分析就是,在垃圾回收之前,对堆中所有的对象进行扫描,看是否被根对象(一定不会被回收的对象)直接或间接引用,如果是则无法被回收,没有被引用则可回收。

Java中对象能否被回收,是根据兑现是否被引用来决定的。如果对象被引用了,说明该对象还在使用,不允许被回收

main栈帧中demo变量存储着Demo实例对象的地址,与Demo实例对象建立了连接关系此时Demo实例对象可以通过demo访问,因此这个对象不能被回收。

当demo为null时,与Demo实例对象不存在连接关系,此时Demo对象就可以被回收了

无需遍历堆可以准确释放对应内存。

  • 加入了synchronized同步锁的对象可以被当作GC Root
  • 本地方法栈内的引用的对象
  • 虚拟机栈中所引用的对象。如各个线程被调用的方法中使用到的参数、局部变量等。
  • 方法区中常量引用的对象。如String Table中里的引用的。
  • 基本数据类型对应的 Class 对象

需要注意的是,上图中的软引用与弱引用实际上也是一个对象,当引用的对象回收时,这些引用对象并不会被回收(因为被GC Root强引用),而是会被放入一个引用队列当中,当内存不足时,会通过遍历引用队列将这些已经没有引用对象的引用释放。

[B@1540e19d
1
[B@677327b6
2
[B@14ae5a5
3
[B@7f31245a
4
[B@6d6f6e28
5
null
null
null
null
[B@6d6f6e28

运行结果

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注